Що краще джава чи сі шарп. Спеціальні ключові слова. Позначення та особливі можливості

Синтаксис

Обидві мови використовують як синтаксичну основу мову програмування C. Зокрема, від неї успадковані без змін:

  • позначення початку/кінця блоку коду фігурними дужками;
  • позначення, асоціативність та пріоритет більшості вбудованих операцій (присвоєння, арифметичні, логічні, побітові операції, операції інкременту/декременту, тернарна умовна операція « ?: »);
  • синтаксис опису та використання змінних та функцій (порядок «тип ім'я», використання модифікаторів, обов'язковість дужок для функцій, опис формальних параметрів);
  • синтаксис всіх основних конструкцій: умовного оператора, циклів, оператора множинного вибору;
  • відсутність процедур (їх замінюють функції типу void);
  • найменування вбудованих елементарних типів (крім bool, Java цей тип називається boolean);
  • використання крапки з комою
  • … і багато дрібніших особливостей.

Все це призводить до того, що програми на Java та C# зовні на перший погляд виглядають надзвичайно схожим на C-програми. В обох мовах зроблено однотипні розширення та доповнення стосовно C (або C++), зокрема, розширено алфавіт і введено власний синтаксис, який підтримує пакети, імпорт описів, визначення одиниць компіляції.

Синтаксичних відмінностей також достатньо.

Синтаксис Java C#
Імпорт статичних імен
(import static)
дозволяє окремо імпортувати деякі або всі статичні методи та змінні класу та використовувати їх імена без кваліфікації в модулі імпортуючого імпортується тільки складання і при кожному використанні статичних імен, що імпортуються, потрібно вказувати клас
Константи в операторі switch повинні відноситися або до цілого чи до перерахованого типу (у 1.7 до списку типів додані рядкові літерали) можна використовувати текстові рядки
Оператор переходу goto від використання goto свідомо відмовилися, проте існує механізм, що дозволяє вийти на зовнішній цикл із вкладеного, помітивши його міткою та використовуючи оператори break , continue разом із міткою (continue<метка>;) goto зберігся, його звичайне використання - передача управління на різні мітки case в операторі switch і вихід із вкладеного циклу
Константи констант як таких немає, замість них використовуються статичні змінні класу з модифікатором final - ефект від їх використання такий самий окреме поняття іменованої типізованої константи та ключове слово const
Точність обчислень з плаваючою точкою Java містить конструкцію strictfp, що гарантує однакові результати операцій із плаваючою точкою на всіх платформах. C# покладається реалізацію, гарантії суворо однакових результатів обчислень немає.
Вимкнення перевірок У Java всі динамічні перевірки включаються/вимикаються лише на рівні пакета C# містить конструкції checked і unchecked , що дозволяють локально включати та вимикати динамічну перевірку арифметичного переповнення.

В цілому синтаксис C# дещо об'ємніший і багатший, ніж Java, зокрема, там є такі особливості, як можливість поділу опису одного класу на кілька модулів, опис властивостей, можливість управління віртуальністю методів.

Механізм роботи з динамічними даними та складання сміття

Обидві мови реалізують одну модель роботи з динамічними даними: об'єкти створюються динамічно за допомогою конструкції new, середовище виконання відстежує наявність посилань на них, а збирач сміття періодично очищає пам'ять від об'єктів, посилань на яких немає. Для оптимізації складання сміття специфікації мов та середовищ виконання не містять обмежень на час життя об'єкта після видалення останнього посилання на нього – збирач працює незалежно від виконання програми, тому реальне знищення об'єкта може статися у будь-який момент після видалення останнього посилання до завершення роботи програми. Насправді збирачі сміття оптимізують виконання так, щоб забезпечити прийнятну витрату пам'яті при мінімальному уповільненні роботи програм.

C# (точніше середовище CLR) дозволяє скасувати виконання фіналізатора для даного об'єкта методом GC.SuppressFinalize(obj) (напр., з'єднання SQL на файловому потоці). Це буває корисним, оскільки фіналізація вважається відносно дорогою операцією під час складання сміття, і об'єкт із фіналізатором «живе» довше.

Об'єктні засоби

Перераховані типи

У Java можуть бути оголошені, лише одномірні масиви. Багатовимірний масив Java - масив масивів. C# є як справжні багатовимірні масиви , так і масиви масивів, які в C # зазвичай називаються «нерівними», або «ступінчастими» (jagged). Багатовимірні масивизавжди «прямокутні» (говорячи у двовимірній термінології), тоді як масиви масивів можуть зберігати рядки різної довжини (знов-таки у двовимірному випадку, у багатовимірному аналогічно). Багатомірні масиви прискорюють доступ до пам'яті (їх покажчик розіменовується лише один раз), а нерівні масиви працюють повільніше, але заощаджують пам'ять, коли всі рядки заповнені. Багатовимірні масиви вимагають для створення лише один виклик оператора new, а східчасті вимагають явно виділяти пам'ять у циклі кожного рядка.

Параметризовані (узагальнені) типи

В обох мовах типи можуть бути параметризовані, що підтримує парадигму узагальненого програмування. Синтаксично визначення типів досить близьке - в обох мовах воно успадковане від шаблонів (templates) C++, хоч і з деякими модифікаціями.

Узагальнення типів Java є суто мовною конструкцією і реалізовані лише в компіляторі. Компілятор замінює всі узагальнені типи на їх верхні межі і вставляє відповідне приведення типів у ті місця, де використовується тип, що налаштовується. В результаті виходить байт-код, який не містить посилань на узагальнені типи та їх параметри. Така техніка реалізації узагальнених типів називається затирання типів(type erasure). Це означає, що інформація про вихідні узагальнені типи під час виконання недоступна, і обумовлює деякі обмеження, такі як неможливість створювати нові екземпляри масивів з аргументів узагальненого типу. Середа виконання Javaне знайома із системою узагальнених типів, внаслідок чого новим реалізаціям JVM знадобилися лише мінімальні оновлення для роботи з новим форматом класів.

C# пішов іншим шляхом. Підтримка узагальненості була інтегрована в саму віртуальне середовищевиконання, вперше з'явившись у .NET 2.0. Мова тут стала лише зовнішнім інтерфейсом для доступу до цих можливостей середовища. Як і Java, компілятор проводить статичну перевірку типів, але на додаток до цього JIT проводить перевірку коректності під час завантаження . Інформація про узагальнені типи повністю присутня під час виконання та дозволяє повну підтримку рефлексії узагальнених типів та створення їх нових реалізацій.

Підхід Java вимагає додаткових перевірокпід час виконання, не гарантує, що клієнт коду слідуватиме відповідності типів, і не забезпечує рефлексії для узагальнених типів. Java не дозволяє спеціалізувати узагальнені типи примітивними (це можна зробити тільки загортаючи примітивні типив класи), у той час як C# забезпечує узагальнення як для типів посилань, так і для типів-значень, включаючи примітивні. Натомість Java пропонує використання загорнутих примітивних типів як параметри (напр., List замість List ), але це дається ціною додаткового виділення динамічної пам'яті. Як у Java, так і в C# спеціалізації узагальненого типу на різних типах посилань дають однаковий код , але для C# середовище виконання динамічно генерує оптимізований код при спеціалізації на типах-значеннях (наприклад, List ), що дозволяє їх зберігати та витягувати з контейнерів без операцій за- та розгортання.

Обробка подій

Java вимагає від програміста ручної реалізації шаблону спостерігача, хоч і забезпечує деякий синтаксичний цукор у вигляді анонімних вкладених класів, що дозволяє визначити тіло класу і відразу створити його екземпляр в одній точці коду.

C# надає широку підтримку програмування на рівні мови, включаючи делегати.NET, мультикастинг, спеціальний синтаксис для завдання подій у класах, операції для реєстрації та розреєстрації обробників події, підступність делегатів та анонімні методи з повним набором семантики замикання.

Замикання пропонуються до включення Java SE 8 . Ці замикання, як делегати C#, мали б повний доступдо всіх локальних змінних у цій галузі видимості, а не лише доступ для читання до змінних, позначених словом final (як з анонімними вкладеними класами).

Перевантаження операцій

Властивості

C# підтримує концепцію «властивостей» - псевдополів класу, до яких забезпечується повністю контрольований доступ шляхом створення методів для отримання та запису значення поля. Описи властивостей виробляються за допомогою конструкцій get і set.

C# також включає так звані індексатори, які можна вважати особливим випадком перевантаження операцій (аналогічним перевантаженням operator в C++), або параметризованими властивостями. Індексатор - це властивість з іменем this , яке може мати один або більше параметрів (індексів), причому індекси можуть бути будь-якого типу. Це дозволяє створювати класи, екземпляри яких поводяться подібно до масивів:

MyList [4] = 5; string name = xmlNode. Attributes ["name"]; orders = customerMap[ theCustomer] ;

Використання властивостей не схвалюється авторитетними програмістами. Зокрема, Джеффрі Ріхтер пише:

«Особисто мені властивості не подобаються, і я був би радий, якби їхню підтримку прибрали з Microsoft .NET Framework та супутніх мов програмування. Причина в тому, що властивості виглядають як поля, насправді є методами.

Відповідно до загальноприйнятого в C# стилю іменування, імена властивостей візуально відрізняються від полів тим, що починаються з великої літери.

Умовна компіляція

C#, на відміну Java, підтримує умовну компіляцію з допомогою директив препроцессора . У ньому також є атрибут Conditional , що означає, що цей метод викликається лише тоді, коли визначена дана константа компіляції. Таким шляхом можна вставляти в код, наприклад, перевірки припущень (assertion checks), які працюватимуть тільки у налагоджувальній версії, коли визначено константу DEBUG . У стандартній бібліотеці.NET такий метод Debug.Assert().

Java версій 1.4 і вище включає можливість перевірки допущень, що включається під час виконання. Крім того, конструкції if з константними умовами можуть розгортатися на етапі компіляції. Існують сторонні реалізації препроцесорів для Java, вони використовуються переважно при розробці програм для мобільних пристроїв.

Простір імен, складання, пакети

C# використовує простору імен(namespace), що нагадують однойменний механізм C++. Кожен клас відноситься до деякого простору імен, ті класи, для яких простір імен не зазначено явно, відносяться до безіменного простору за промовчанням. Простір імен можуть бути вкладеними один в одного.

У Java є пакети, частково схожі простору імен C#. Пакети можуть бути вкладеними, кожен клас, що описується, відноситься до деякого пакету, за відсутності явної вказівки пакета клас відноситься до глобального безіменного пакета.

В обох мовах для звернення до об'єкта, оголошеного в іншому просторі імен або пакеті, потрібно оголосити у програмі необхідний пакет (простір імен) як використовуваний. Звернення до об'єкта здійснюється через кваліфіковане ім'я, як кваліфікатор використовується ім'я пакета (простору імен). Якщо потрібне звернення до об'єкта без кваліфікації, програмний модуль повинен містити директиву розіменування: using C# і import Java.

У C# простору імен ніяк не пов'язані з компільованими модулями (складання, або assembly в термінології Microsoft). Декілька збірок можуть містити один і той же простір імен, в одній збірці може оголошуватися кілька просторів імен, не обов'язково вкладених. Модифікатори області видимості C# не пов'язані з просторами імен. У Java оголошені одному пакеті класи за умовчанням утворюють єдиний компилированный модуль. Модифікатор області видимості за умовчанням (відсутність явної вказівки) обмежує область видимості полів та методів класу межами пакета.

У Java структура файлів і каталогів вихідних текстів пакета за замовчуванням пов'язана зі структурою пакета - пакету відповідає каталог, що входять до нього підпакетам - підкаталоги цього каталогу, файли вихідних текстів розташовуються в каталогах, які відповідають пакету або підпакету, до якого вони входять. Таким чином, дерево вихідних текстів повторює структуру пакета. У C# місцезнаходження файлу з вихідним текстомне пов'язане з його простором імен.

Розташування вихідного тексту у файлах

У C# класи можуть розташовуватися у файлах довільним чином. Ім'я файлу вихідного коду не пов'язані з іменами визначених у ньому класів. Дозволяється розташувати в одному файлі кілька загальнодоступних (public) класів. Починаючи з версії 2.0, C# дозволяє також розбити клас на два і більше файлів (ключове слово partial). Остання особливість активно використовується візуальними засобами побудови інтерфейсу: частина класу, в якій знаходяться поля та методи, керовані конструктором інтерфейсу, виділяються в окремий файл, щоб не захаращувати файл, що автоматично генерується, безпосередньо редагований програмістом.

У Java кожен файл може містити лише один загальнодоступний (public) клас, причому Java вимагає, щоб ім'я файлу збігалося з ім'ям цього класу, що виключає плутанину в іменах файлів та класів. Більше того, згідно з рекомендованою Sun угодою про оформлення коду, розмір файлу вихідного коду не повинен перевищувати 2000 рядків коду, оскільки у файлі більшого розміру складніше розбиратися. Великий розмірфайл також вважається ознакою поганого проектного рішення.

Винятки

Обидві мови підтримують механізм обробки винятків, синтаксично оформлений абсолютно однаково: у мові є оператор генерації винятку throwта блок обробки винятків try()catch()()finally(), що забезпечує перехоплення виключень, що виникли всередині блоку, їх обробку, а також гарантоване виконання завершальних дій.

Java підтримує перевірені (checked) винятки: програміст повинен явно вказати для кожного методу типи винятків, які метод може викинути, ці типи перераховують в оголошенні методу після ключового слова throws. Якщо метод використовує методи, що викидають виключення, що перевіряються, він повинен або явно перехоплювати всі ці винятки, або містити їх у власному описі. Таким чином, код явно містить перелік винятків, які можуть бути викинуті кожним методом. Ієрархія типів винятків містить також два типи (RuntimeException та Error), спадкоємці яких не є перевіреними і не повинні описуватися. Вони виділені для винятків часу виконання, які можуть виникнути в будь-якому місці, або зазвичай не можуть бути оброблені програмістом (наприклад, помилки середовища виконання) і не повинні вказуватися в оголошенні throws.

C# виключення, що перевіряються, не підтримує. Їхня відсутність є свідомим вибором розробників. Андерс Хейлсберг, головний архітектор C#, вважає, що в Java вони були певною мірою експериментом і себе не виправдали.

Паралельне програмування

У цілому нині механізми паралельного програмування в C# аналогічні тим, що надає Java, відмінність полягає у деталях реалізації. В обох випадках є бібліотечний клас Thread, що реалізує поняття потоку. Java надає два способи створення власних потоків: шляхом розширення класу Thread, або шляхом реалізації інтерфейсу Runnable. В обох випадках програміст повинен визначити успадкований (входить до інтерфейсу) метод run(), що містить тіло потоку - код, який буде виконуватися. C# замість цього використовує механізм делегатів: для створення потоку створюється екземпляр стандартного класу Thread, якому передається як параметр конструктора делегат, що містить метод - тіло потоку.

В обох мовах є можливість створити синхронно виконуваний блок коду; Java це робиться за допомогою оператора synchronized(), в C# - оператором lock(). Java також має можливість оголошувати синхронні методи, використовуючи модифікатор synchronized в заголовку опису методу. Такі методи при виконанні блокують свій об'єкт-господар (таким чином, із синхронізованих методів класу, для того самого екземпляра, одночасно може виконуватися тільки один, інші чекатимуть). Аналогічна можливість в.NET реалізується за допомогою атрибуту реалізації методу MethodImplAttribute MethodImplOptions.Synhronized, але, на відміну від Java, ця можливість формально не є частиною мови C#.

В обох мовах доступні також ідентичні засоби синхронізації, засновані на надсиланні та очікуванні сигналу від одного потоку до іншого (іншим). У Java це методи notify(), notifyAll() і wait(), C# - методи Pulse(), PulseAll(), Wait() (трійки методів функціонально попарно аналогічні). Відмінність полягає лише в тому, що Java ці методи (і, відповідно, функціональність монітора) реалізується в класі Object, тому для синхронізації не потрібно ніяких додаткових бібліотек, а в C# ці методи реалізовані як статичні в окремому бібліотечному класі Monitor. У C# стандартна бібліотека містить також кілька додаткових примітивів синхронізації паралельного виконання потоків: м'ютекси, семафори, таймери, що синхронізують. З версії 1.5 JDK SE включені пакети java.util.concurrent, java.util.concurrent.atomic і java.util.concurrent.locks містять вичерпний набір засобів для реалізації паралельних обчислень.

Низькорівневий код

На сьогоднішній день жодна складова частина середовища Javaне стандартизується Ecma , ISO , ANSI або будь-який інший сторонньою організацієюстандартів. У той час як Sun Microsystems зберігає необмежені виняткові юридичні права на модифікацію та ліцензування своїх торгових марок Java, Sun добровільно бере участь у процесі, що називається Java Community Process (JCP), який дозволяє зацікавленим сторонам пропонувати зміни в будь-які Java-технології Sun (мова, інструментарій) , API) через консультації та експертні групи. За правилами JCP, будь-яка пропозиція щодо зміни в JDK, середовищі виконання Java або специфікації мови Javaможе бути односторонньо відкинуто Sun, оскільки його схвалення потрібен голос «за» із боку Sun. Від комерційних учасників JCP вимагає членських внесків, у той час як некомерційні організації та приватні особи можуть брати участь у ньому безкоштовно.

Ліцензія

У той час як "Java" - торгова марка Sun trademark, і тільки Sun може ліцензувати ім'я "Java", існують численні вільні проекти, частково сумісні з Sun Java. Наприклад, GNU Classpath і GNU Compiler for Java (GCJ) поставляють вільну бібліотеку класів та компілятор, частково сумісні з поточною версією Sun Java. Наприкінці 2006 року Sun оголосила, що весь вихідний код Java, за винятком закритого коду, на який вони не зберігають права, буде випущений до березня 2007 року як вільне програмне забезпечення під видозміненою ліцензією GPL . Sun в даний час поширює свою HotSpot Virtual Machine і компілятор Java під ліцензією GPL, але стандартне середовище виконання Java зараз немає вільної ліцензії . Оскільки Sun збереже право власності на свій вихідний код Java, випуск під ліцензією GPL не заборонить Sun розповсюджувати невільні або невідкриті версії Java, або надавати ліцензії іншим .

C#, середовище виконання CLI і більшість відповідної бібліотеки класів стандартизовані і можуть вільно реалізовуватися без ліцензії. Вже реалізовано кілька вільних систем C#, зокрема Mono та DotGNU. У проекті Mono також реалізовано багато нестандартних бібліотек Microsoft шляхом вивчення матеріалів Microsoft, аналогічно GNU Classpath і Java. Метою проекту Mono є уникнути зазіхань на будь-які патенти або копірайти, і проект може вільно поширюватися та використовуватись під ліцензією GPL. Microsoft в даний час поширює версію свого середовища виконання .NET для некомерційного використання.

Використання

Спільнота

Java побудована більш відкритої культурі з високою конкурентністю фірм у різних галузях функціональності. Більшість додаткових бібліотек доступна під вільними ліцензіями з відкритим вихідним кодом. Також Sun вітає практику опису будь-якої функціональності у вигляді специфікації (див. процес JCP), залишаючи реалізацію стороннім розробникам(Можливо, надаючи еталонну реалізацію). Отже, вирішується питання незалежності виробника ПЗ.

Незважаючи на існування Mono, C# тісно прив'язує розробників до платформи Microsoft (включаючи ОС, офісні рішення). Таким чином, користувач програмного забезпечення, написаного на .NET, часто не має вибору у використанні різних компонентів системи. Це призводить до так званого vendor-locking, при якому виробник стороннього програмного забезпечення може диктувати покупцеві практично будь-які умови на підтримку впровадженого проекту. У той час, як користувач програми Java, як правило, може сам вибрати постачальника додаткового програмного забезпечення (такого, як БД, ОС, сервера додатків тощо).

Популярність та розвиток

Java старше, ніж C# і побудована на великій і активній базі користувача, ставши lingua francaв багатьох сучасних областяхінформатики, особливо таких, де задіяні мережі. Java домінує в курсах програмування американських університетів та коледжів, і літератури з Java сьогодні набагато більше, ніж за C#. Зрілість і популярність Java призвели до більшого числа бібліотек і API на Java (багато з яких відкриті), ніж C#.

На відміну від Java, C# - мова відносно нова. Microsoft вивчила існуючі мови, такі як Java, Delphi та Visual Basic , та змінила деякі аспекти мови для кращої відповідності потребам деяких типів програм.

Відносно Java можна почути критику, що вона повільно розвивається, в ній не вистачає деяких можливостей, що полегшують модні шаблони програмування та методології. Мова C# критикують у тому, що його розробники, можливо, надто поспішають догодити миттєвим течіям у програмуванні ціною фокусування та простоти мови. Очевидно, проектувальники Java зайняли більш консервативну позицію щодо додавання великих нових можливостей до синтаксису мови, ніж в інших сучасних мовах - можливо, не бажаючи прив'язати мову до течій, які в довгостроковій перспективі можуть завести в глухий кут. З випуском Java 5.0 ця тенденція багато в чому була порушена, тому що в ній ввели кілька великих нових можливостей мови: цикл типу foreach, автоматичне загортання, методи змінним числомпараметрів, перераховані типи, узагальнені типи та інструкції (всі вони є і в C#).

C#, у свою чергу, розвивається швидше, набагато слабше обмежуючи себе у додаванні нових проблемно-орієнтованих можливостей. Особливо ця тенденція виявилася у версії C# 3.0, у якій, наприклад, з'явилися SQL-подібні запити. (Нові можливості при цьому будуються так, щоб мова залишалася мовою загального призначення. Докладніше про C# 3.0 см у статті про C#). Проблемно-орієнтовані доповнення до Java розглядалися, але принаймні на сьогоднішній день були відкинуті.

Ринок

З появи C# він постійно порівнюється з Java. Неможливо заперечувати, що C# та його кероване середовище CLR багатьом зобов'язані Java та її JRE (Java Runtime Environment).

Можна сперечатися, чи є розробка C# певною мірою результатом визнання Майкрософтом того, що середовище керованого коду, де лідирує Java, має безліч переваг у зростаючому мережевому світіособливо при появі інтернету на пристроях, відмінних від персональних комп'ютерів, і при зростаючій важливості мережевої безпеки. До створення C# Microsoft модифікувала Java (створивши J++), щоб додати можливості, що працюють тільки на ОС Windows, порушивши таким чином ліцензійну угоду Sun Microsystems. Поки Microsoft перебувала на другій фазі своєї бізнес-стратегії, відомої як "Embrace, Extend, and Extinguish", розвиток J++ було зупинено позовом, поданим Sun'ом. Будучи позбавленою можливості розробляти клон Java з потрібними їй властивостями, Microsoft створила альтернативу, яка більше відповідала їхнім потребам та баченню майбутнього.

Незважаючи на такий неспокійний початок, стає все більш очевидним, що дві мови рідко конкурують одна з одною на ринку. Java домінує в мобільному секторі та має багато прихильників на ринку веб-додатків. C# отримав гарне визнання на ринку настільних програм Windows і завдяки ASP.NET, C# також є гравцем і на ринку веб-додатків.

Настільні програми

Для обох мов є набір бібліотек, що надають можливості для побудови інтерфейсу користувача для настільних додатків. У випадку Java це мультиплатформні бібліотеки Swing та SWT, а також ряд менш поширених. В принципі, кожна з них дозволяє створювати кросплатформні настільні програми на Java.

Для C# на платформі Windows є основною бібліотекою, що реалізує графічний інтерфейсКористувача в настільних додатках є Windows.Forms, що належить Microsoft і реалізована тільки для Windows, а для інших платформ - gtk#, виконана в рамках проекту Mono. Спроби вільної реалізації Windows.Forms робилися і робляться (наприклад, у проекті DotGNU), проте вони, через закритість оригіналу, неминуче страждають вторинністю і неповнотою, навряд чи можуть конкурувати з реалізацією від Microsoft і тому можуть застосовуватися хіба що для портування Windows, що запізнюється. програм на інші платформи. Розробки, що спочатку базуються на Windows, будуються зазвичай на Windows.Forms, і їх перенесення на іншу платформу стає скрутним. Розробки на C# в середовищі Mono, що використовують gtk#, переносяться, але їх значно менше.

В силу особливостей мови ручне використання графічних бібліотек Java дещо складніше. Архітектура графічних бібліотек Java більш складна для розуміння розробника-початківця, в той же час, це змушує його розвиватися в професійному плані. C# за рахунок наявності вбудованих засобів програмування подій приховує від розробника деталі обробки подій і деякі інші моменти, полегшуючи розробку інтерфейсу. На платформі .NET спочатку широко використовувалися візуальні розробники інтерфейсу. Все це дає можливості для швидкої розробкиінтерфейсу настільних додатків за невисокої кваліфікації програміста.

В останні кілька років Sun Microsystems сконцентрувалася на ще ширшому впровадженні Java ринку настільних додатків. У версії платформи JRE 6 (2006 рік) акцент зроблено на покращенні взаємодії з графічним оточенням користувача. Остання версія JVM від Sun (JDK 6 update 10) включає безліч покращень для створення інтерфейсу користувача. Зокрема, прозорі форми та вікна непрямокутної форми. Останні версії інтегрованих середовищ розробки Java (наприклад, NetBeans) також включають значно покращені графічні будівельники інтерфейсу користувача.

C#, нарівні з Java, поступово стає популярним на кількох операційні системина основі Linux та BSD. Реалізація проекту Mono була юридично безболісним процесом, оскільки CLR та мова C# стандартизовані Ecma та ISO, і будь-яка може їх реалізовувати, не турбуючись про правовий бік справи. У той же час, слід зазначити, що написаний додаток під середовищем Windowsможе мати значні проблеми запуску під іншою ОС.

Серверні програми

На цій арені, можливо, дві мови найближче до того, щоб вважатися конкурентами. Java з її платформою J2EE (Java(2) Enterprise Edition) і C# з його ASP.NET змагаються в області створення динамічного веб-контенту та додатків.

На цьому ринку широко використовуються та підтримуються обидві мови, разом із комплектом інструментів та супроводжуючих продуктів, наявних для JavaEE та .NET.

Мобільні додатки

J2ME (JavaME, Java(2) Micro Edition) має дуже широку базу на ринках мобільних телефоніві КПК , де тільки найдешевші пристрої позбавлені KVM (урізана Java Virtual Machine для пристроїв з обмеженими ресурсами). Програми Java, включаючи безліч ігор, зустрічаються повсюдно.

У той час як майже всі телефони включають KVM, ці можливості використовуються більшістю користувачів не дуже інтенсивно. Програми Javaна більшості телефонів зазвичай складаються із систем меню, невеликих ігор і т. д. Повноцінні програми для мобільних телефонів рідкісні.

Передові технології

C Sharp- Цей термін має й інші значення, див. Правильний заголовокцієї статті C#. Він показаний некоректно через технічні обмеження. C# Семантика: імперативний Клас мови: мультипарадигменний: об'єктно орієнтований, … Вікіпедія

Visual J Sharp- Правильне заголовок цієї статті Visual J#. Він показаний некоректно через технічні обмеження. Visual J# створена фірмою Майкрософт для платформи.NET Framework інтегроване середовище розробки Java подібною мовою. Особливо… … Вікіпедія

F Sharp- Цей термін має й інші значення, див. F (значення). Правильний заголовок цієї статті F #. Він показаний некоректно через технічні обмеження. F# Клас мови: мультипарадигменний: функціональне, об'єктно орієнтоване, … Вікіпедія

Sing Sharp- Правильне заголовок цієї статті Sing#. Він показаний некоректно через технічні обмеження. Sing# Клас мови: мультипарадигмовий: структурний, імперативний, об'єктно орієнтований, подієво орієнтований, функціональний, … … Вікіпедія

MC Sharp- MC# (читається як «ем сі шарп», mcsharp), Multiprocessor C# мову програмування. MC# високорівнева об'єктно орієнтована мова паралельного програмування для платформи.NET, що підтримує створення програм, що працюють у … Вікіпедія

Visual C Sharp

Visual C Sharp .NET- Microsoft Visual Studio Зовнішній вигляд Visual Studio 2008 SP1 з програмою на мові C# Windows VistaТип Середовище розробки програмного забезпечення … Вікіпедія

ECMAScript- Клас мови: мультипарадигменний: об'єктно орієнтоване, узагальнене, функціональне, імперативне, аспектно орієнтоване, подієво орієнтоване, прототипне програмування З'явився у: 1995 Автор(и) Вікіпедія

А не явне звільнення пам'яті. Обидва включають у свій синтаксис механізми синхронізації.

І в Джаві, і в C# є сильні та слабкі посилання на об'єкти. Джава дозволяє зареєструвати слухач (listener), який отримуватиме повідомлення, коли посилання піддається складання сміття, що дає поліпшення продуктивності WeakHashMap, Якого немає в C #. Обидві мови дозволяють виконувати код користувача, коли складання сміття піддається об'єкт. У механізмі цього служить спеціальний метод-фіналізатор, виражений через знайомий синтаксис деструктора C ++. У Джаві це досягається перевизначенням методу finalize, що декларується у класі Object.

Типи даних

Обидві мови підтримують ідею (відомих у C# як типи-значення - value types), і обидва для трансляції примітивних типів в об'єктні забезпечують їхнє автоматичне «загортання» в об'єкти (boxing) і «розгортання» (unboxing). C# має більше примітивних типів, ніж Джава, за рахунок беззнакових цілих типів (unsigned), наявних парно до всіх знакових, і спеціального типу decimal для високоточних обчислень з плаваючою комою. У Джаві відмовилися від більшості беззнакових типів задля простоти. Зокрема, у Джаві немає примітивного типу беззнакового байта.

Позначення та особливі можливості

У Джаві є спеціальний синтаксис імпорту статичних імен (import static), що дозволяє використовувати скорочені імена деяких чи всіх статичних методів та змінних класу. У C# є синтаксис статичного класу (static class), що обмежує клас лише статичними методами, але немає можливості вказувати лише ці методи без явного завдання класу щоразу.

Спеціальні ключові слова

Ключове слово Можливість, приклад використання
get, set Синтаксис C# підтримує.
out, ref C# підтримує вихідні параметри методів, що дозволяє повертати кілька значень.
switch C# оператор switch працює також на рядках.
strictfp Джава використовує strictfp для гарантування незмінності результатів операцій із плаваючою точкою на всіх платформах.
checked, unchecked C# вирази або блоки checked можуть включати перевірку арифметичного переповнення під час виконання.
using Ключове слово using в C#"s забезпечує ліквідацію або закриття створеного об'єкта на виході з: using (StreamWriter file = new StreamWriter("test.txt")) ( file.Write("test"); )
goto C# підтримує оператор переходу. Він може бути іноді корисним, хоча зазвичай рекомендуються структурованіші методи передачі управління (через що від нього і відмовилися в Джаві). Звичайне використанняключового слова goto C# - передача управління на різні мітки case в операторі switch . switch(color) ( case Color.Blue: Console.WriteLine("Color is blue"); break; case Color.DarkBlue: Console.WriteLine("Color is dark"); goto case Color.Blue; // ... )

Обробка подій

Джава вимагає від програміста ручної реалізації шаблону спостерігача, хоч і забезпечує деякий у вигляді анонімних, що дозволяє визначити тіло класу і відразу створити його екземпляр в одній точці коду. Ця можливість зазвичай використовується для створення спостерігачів.

C# надає широку підтримку програмування на рівні мови, включаючи делегати.NET, мультикастинг, спеціальний синтаксис для завдання подій у класах, операції для реєстрації та розреєстрації обробників події, підступність делегатів та анонімні методи з повним набором семантики .

Замикання пропонуються до включення Java SE 7 . Ці замикання, як делегати в C#, мали б повний доступ до всіх локальних змінних у цій галузі видимості, а не тільки для читання до змінних, позначених словом final (як з анонімними вкладеними класами).

Перевантаження операцій

C# включає великий набір зручностей нотації, багато з яких, такі як перевантаження операцій і задане користувачем, знайомі програмуючим на C++. У ньому також є явна реалізація методів інтерфейсу, що дозволяє класу реалізовувати методи інтерфейсу окремо від власних методів або давати різні реалізації однойменних методів, що належать двом різним інтерфейсам.

Джава не включає перевантаження операцій, оскільки її зловживання може призвести до коду, що важко читати і важко налагоджується. Водночас відсутність навантаження в Джаві робить її малопридатною для деяких математичних програм.

Методи

У C# методи за замовчуванням не є і повинні для цього явно оголошуватись ключовим словом virtual . У Джаві, навпаки, все відкриті методиКрім статичних, є віртуальними. Ключове слово Java final є аналогом sealed C# і дозволяє заборонити створення методу з такою ж сигнатурою в похідних класах. Віртуальність гарантує потрібне перекриття для виклику, але при виконанні накладає деякі витрати на виклики, оскільки ці виклики зазвичай не проходять інлайн-підстановку і вимагають додаткового звернення до . Однак деякі реалізації JVM, включаючи реалізацію Sun, реалізують інлайн-підстановку віртуальних методів, що найбільш часто викликаються.

C# вимагає явного оголошення про намір перекрити (override) віртуальний методу похідному класі. Такий намір описується ключовим словом override. Якщо перекриття не входить у наміри програміста, і потрібно просто ввести новий віртуальний метод з тим же ім'ям і сигнатурою, що закриває (shadowing) старий, тоді потрібно інше ключове слово, new . Якщо жодне з цих слів не зазначено, це веде до помилки компіляції. У Джаві будь-який метод завжди віртуально перекриває метод базового класу з тим самим ім'ям і сигнатурою, якщо він є. Така поведінка потенційно небезпечна, якщо базовий клас створений іншим розробником, і в новій його версії вводиться такий самий метод, який вже є у похідному класі; у цьому випадку існуючий метод із похідного класу перекриє знову введений метод у базовому, що не входить до намірів обох розробників.

Умовна компіляція

C#, на відміну Java, підтримує умовну компіляцію з допомогою директив . У ньому також є атрибут Conditional , що означає, що цей метод викликається лише тоді, коли визначена дана константа компіляції. Таким шляхом можна вставляти в код, наприклад, перевірки припущень (assertion checks), які працюватимуть тільки у налагоджувальній версії, коли визначено константу DEBUG . У стандартній бібліотеці.NET це метод Debug.Assert(). Java версій 1.4 і вище включає можливість перевірки допущень, що включається під час виконання.

Простори імен та вихідні файли

Простір імен C# більше нагадують C++. На відміну від Джави, розташування файлу з вихідним текстом ніяк не пов'язане з його простором імен. Хоча, строго кажучи, розташування вихідних файлів у Джаві не обов'язково відображає структуру каталогів пакета, але така поведінка за умовчанням.

Джава вимагає, щоб ім'я вихідного файлуточного відповідало імені єдиного загальнодоступного (public) класу, визначеного в ньому, тоді як C# дозволяє в одному файлі визначати кілька загальнодоступних класів і не накладає жодних обмежень на ім'я файлу, а також (у версії 2.0 і вище) дозволяє розбити клас на два та більше файлу (ключове слово partial).

Винятки

Джава підтримує перевірені (checked), примусово забезпечуючи повний лов та обробку всіх виняткових ситуацій. Усі винятки, які метод може викинути, повинні перераховуватись у його оголошенні за допомогою ключового слова throws. C# виключення, що перевіряються, не підтримує. Одні розробники вважають, що виключення, що перевіряються, дуже корисні для забезпечення гарного стилюпрограмування. Інші, включаючи головного архітектора C#, заперечують, що вони в Джаві були певною мірою експериментом і себе не виправдали.

Один з аргументів проти виключень, що перевіряються - те, що при їх використанні зміна внутрішнього коду функції може призвести до викиду нових винятків, що вимагає зміни в оголошенні цієї функції та всіх інших, що її викликають. Зрештою для збереження сумісності інтерфейсів часто просто стали оголошувати функції як throws Exception , зводячи таким чином нанівець всю ідею винятків, що перевіряються. Інший спосіб збереження сумісності інтерфейсу в Джаві - зловити нововведений виняток, завернути його в старе оголошене і знову викинути. Наприклад, якщо метод змінили так, що він починає звертатися до бази даних замість файлової системи, то він може сам ловити SQLException і викидати замість нього знову створюваний IOException, оскільки користувач методу не повинен знати про деталі його внутрішньої реалізації.

Низькорівневий код

Реалізації

JVM та CLR

Джава всюдисуща у різноманітних операційних системах та середовищах. Існують численні реалізації, іноді з відкритими вихідними кодами.

Технологія ClickOnce пропонує подібну функціональність для Java Webstart, але вона є тільки для клієнтів Windows. Internet Explorer на Windows теж вміє показувати. NET Windows Forms, що дає аплетоподібну функціональність, але обмежено конкретним браузером.

Стандартизація

Мова C# визначається не Microsoft, а комітетами стандартів та . У той час як Sun зберігає копірайт і право вето на платформу Java, остання великою мірою управляється через Java Community Process]] (JCP), який дозволяє зацікавленим сторонам залучатися до визначення нових версій та можливостей специфікації технології Java.

Стандарти ECMA та ISO для C# і .NET визначають мову, інфраструктуру CLI та базові класи(Base Class Library, або BCL). Стандарти не включають багато нових бібліотек, реалізований Microsoft поверх стандартного каркаса, такі як бібліотеки для баз даних, GUI та веб-додатків ( , і ). Проте Microsoft формально погодилося не переслідувати у судовому порядку проекти спільноти за реалізацію цих бібліотек.

Використання

Спільнота

Джава побудована більш відкритої культурі з високою конкурентністю фірм у різних галузях функціональності. Хоча це повністю вирішує проблему незалежності виробників, але додає до мови додаткову складність. Для успішного використання бібліотек і компонентів треба знати не тільки Джаву, а й усі різноманітні конкуруючі між собою оболонки та каркаси та різні «фішки» реалізацій.

Популярність та розвиток

Джава старша, ніж C# і побудована на великій і активній базі користувача, ставши у багатьох сучасних галузях інформатики, особливо таких, де задіяні . Джава домінує в курсах програмування американських університетів та коледжів, і літератури з Джави сьогодні набагато більше, ніж за C#. Зрілість і популярність Джави привели до більшої кількості бібліотек і API на Джаві (багато з яких відкриті), ніж на C#.

На відміну від Джави, C# - мова відносно нова. Microsoft вивчила існуючі мови, такі як Джава і , і змінила деякі аспекти мови для кращої відповідності потреб деяких типів додатків. З часом тимчасова перевага Джави стає менш значущою.

Щодо Джави можна почути критику, що вона повільно розвивається, у ній не вистачає деяких можливостей, які полегшують модні шаблони програмування та методології. Мова C# критикують у тому, що його розробники, можливо, надто поспішають догодити миттєвим течіям у програмуванні за рахунок фокусування та простоти мови. Очевидно, проектувальники Джави зайняли більш консервативну позицію щодо додавання великих нових можливостей у синтаксис мови, ніж в інших сучасних мовах – можливо, не бажаючи прив'язати мову до течій, які у довгостроковій перспективі можуть завести в глухий кут. З випуском Java 5.0 ця тенденція багато в чому була порушена, так як в ній ввели кілька великих нових можливостей мови: цикл типу foreach , автоматичне загортання, методи зі змінним числом параметрів, типи, узагальнені типи і анотації (усі вони присутні і в C #) .

C#, у свою чергу, розвивається швидше, набагато слабше обмежуючи себе у додаванні нових проблемно-орієнтованих можливостей. Особливо ця тенденція проявилася в версії C# 3.0, що готується до випуску, в якій, наприклад, з'явилися -подібні запити. (Нові можливості при цьому будуються так, щоб мова залишалася мовою загального призначення. Докладніше про C# 3.0 див.

Можна сперечатися, чи є розробка C# певною мірою результатом визнання Майкрософтом того, що середовище керованого коду, де лідирує Джава, має безліч переваг у зростаючому мережевому світі, особливо при появі інтернету на пристроях, відмінних від персональних комп'ютерів, і при зростаючій важливості мережевої безпеки. До створення C# Microsoft модифікувала Джаву (створивши), щоб додати можливості, що працюють тільки на ОС, порушивши таким чином ліцензійну угоду. Поки що Microsoft перебувала на другій фазі своєї бізнес-стратегії, відомої як , розвиток J++ було зупинено позовом, поданим Sun"ом. Будучи позбавленою можливості розробляти клон Джави з потрібними їй властивостями, Microsoft створила альтернативу, яка більше відповідала їх потребам та баченню майбутнього.

Незважаючи на такий неспокійний початок, стає все більш очевидним, що дві мови рідко конкурують одна з одною на ринку. Джава домінує у мобільному секторі та має багато прихильників на ринку веб-додатків. C# отримав гарне визнання на ринку настільних програм Windows і проштовхується Майкрософтом як основну мову програм Windows. Завдяки C# також є гравцем і на ринку веб-додатків.

Настільні програми

Джаву іноді звинувачують у тому, що вона багато обіцяє і мало дає, коли йдеться про настільні програми. Хоча її віконні бібліотеки AWT (Abstract Windowing Toolkit) і можуть похвалитися великою кількістю можливостей, Джаве довелося поборотися, щоб утвердитися на ринку настільних додатків. Її сувора відданість принципу<пишем один раз, используем везде>ускладнює використання по максимуму специфічних можливостей та режимів роботи в кожній конкретній настільній системі. В результаті написані на Джаві настільні програми часто виглядають зовні як<чужие>на тій платформі, де вони виконуються.

Sun Microsystems, на думку деяких, також зволікала з просуванням Джави в середу розробників та користувачів так, щоб вона виглядала привабливо при виборі платформи для настільних додатків. Навіть такі технології, як Java Web Start, у яких мало суперників серед мов та платформ, просувалися слабко.

Випуск Джави версії 6.0, що передбачається в 2006 році, заново фокусується на настільному ринку - з великим набором нових та цікавих інструментів для кращої та більш тісної інтеграції з настільним середовищем.

Передові технології

Джава прийнята як офіційний програмний засіб для використання в наступному поколінні стандарту DVD, через інтерактивну платформу BD-J. Це означає, що такий інтерактивний вміст, як меню, ігри, скачування і т.д., на всіх дисках DVD Blu-rayбуде створюватись на платформі Java.

Java vs. C#… Що може бути краще за вічну суперечку? Ні, ця стаття не присвячена черговому бенчмарку, і навіть не є holy war, не стоїть навіть питання: «хто крутіший».

Для кожного завдання є свій інструмент. Порівнювати C# і Ruby, наприклад, немає сенсу, т.к. їх цільове призначення зовсім різне, та й природа також. Однак саме C# і Java є найближчими за своєю філософією.

Дуже часто колеги, які пишуть на Java, навіть не підозрюють про багато (!!!) речей, які надає (або, навпаки, не надає) C#.

Якщо Вам цікаво подивитися на C# та Java без суб'єктивізму, а також дізнатися внутрішній пристрійтієї чи іншої можливості, тоді вперед.

▌ Трохи історії

Мова C# з'явилася 2001 року, яке розробка розпочато ще 1999-го гг. Тоді він був дуже схожий на Java 1.4. Однак сучасний C#, якого ми знаємо, слід починати розглядати з версії 2.0 (що відповідає виходу Java 5).

Існує думка, що C# багато чого запозичує з Java. Проте я категорично не згоден із цим. На мою думку, C# багато в чому є C «з об'єктами», або C++ «з людським обличчям».

Сподіваюся, що стаття та докази в ній підтвердять це твердження.
Переказувати вікіпедію я не буду. Тому відразу ж рушимо далі і пройдемося ключовим відмінностямта переваг.

Спочатку ми подивимося можливості самих JVM і CLR (Common Language Runtime), далі вже розглянемо синтаксичний цукор C#.

▌ Епізод I: Bytecode

І.NET, і Java використовують bytecode. Звичайно, крім самого формату, існує одна дуже важлива відмінність – поліморфність.

CIL (Common Intermediate Language, він же MSIL, він просто IL) – є байт-кодом з поліморфними (узагальненими) інструкціями.

Так, якщо в Java використовується окрема інструкція для кожного типу операцій з різними типами(наприклад: fadd- Додавання 2-х float, iadd- Складання 2-х integer), то в CIL для кожного виду операцій існує лише одна інструкція з поліморфними параметрами (наприклад, існує тільки одна інструкція - add, що виробляє додавання та float, та integer). Питання вирішення створення відповідних x86-інструкцій лягає на JIT.

Кількість інструкцій у обох платформ приблизно однакова. Порівнюючи список команд байт-коду Java і CIL, видно, що 206 у Java, і 232 - CIL, проте не забуваємо, що у Java багато команд просто повторюють функціонал один одного.

▌ Епізод III: Generics (parameterized types || parametric polymorphism)

Як відомо, Java використовується механізм type erasure, тобто. підтримка generics забезпечується лише компілятором, але з рантаймом, і після компіляції інформація про тип не буде доступна.

Наприклад, код:

List strList = новий ArrayList (); List intList = новий ArrayList (); bool areSame = strList.getClass() == intList.getClass(); System.out.println(areSame);
Виведе true.

При цьому замість узагальненого типу Tстворюється екземпляр об'єкта типу java.lang.Object.

List strList = новий ArrayList (); strList.add("stringValue"); String str = strList.get(0);
Буде перетворений на вигляд:

List list = новий ArrayList(); list.add("stringValue"); String x = (String) list.get(0);
Таким чином, вся політика безпеки типів руйнуєтьсямиттєво.

NET, навпаки, має повну підтримку generics як compile-time, і run-time.

Так що ж потрібно реалізувати для повної підтримки generics в Java? Натомість краще подивимося, що зробила команда розробників.NET'a:

  • Підтримка generics на рівні Common Type System для крос-мовної взаємодії
  • Повна підтримка з боку Reflection API
  • Додавання нових класів/методів до базових класів (Base Class Library)
  • Зміни у самому форматі та таблицях метаданих
  • Зміни в алгоритмі виділення пам'яті рантаймом
  • Додавання нових структур даних
  • Підтримка generics з боку JIT (code-sharing)
  • Зміни у форматі CIL (нові інструкції байт-коду)
  • Підтримка з боку верифікатора CIL-коду
Тобто. generics доступні не лише під час компіляції, а й під час виконання без втрати чи зміни інформації про тип. Також зникає потреба у boxing/unboxing.

▌ Епізод IV: Types

Java є повністю ГО-мовою. Із цим можна посперечатися. І ось чому: примітивні типи (integer, float тощо) не успадковуються від java.lang.Object. Тому generics Java не підтримують primitive types.

Адже в по-справжньому ГО-мови everything is object.

Це не єдине обмеження. Також неможливо створити власні примітивні типи.

C# дозволяє це робити. Ім'я цих структур – struct.

Наприклад:

Public struct Quad ( int X1; int X2; int Y1; int Y2; )
Також generics C# дозволяють використовувати value types (int, float і т.д.)

Якщо Java потрібно писати так:

List intList = новий ArrayList ();
Але не можна так:

List intList = новий ArrayList ();
C# дозволяє використання примітивних типів.

Тепер ми підійшли до теми ієрархії типів .NET.

В.NET існує 3 види типів: value, reference та pointer types.

Отже, value type– аналог primitive type із Java. Однак успадковується від System.Object, живе над купі, а стеку (а тепер застереження: розташування value type залежить з його життєвого циклу, наприклад, за участю у замиканні автоматично відбувається boxing).

Reference type– являє собою те саме, що і reference types в Java.

Pointer type– є незвичайною властивістю.NET'a. Справа в тому, що CLR дозволяє працювати з вказівниками безпосередньо!

Наприклад:

Struct Point ( public int x; public int y; ) unsafe static void PointerMethod() ( Point point; Point* p = p->x = 100; p-> y = 200; Point point2; Point* p2 = (*p2 ).x = 100;(* p2).y = 200;
Дуже схоже на C++ код, чи не так?

▌ Епізод V: Можливості C#

Спочатку визначимося, що вміє C#:
  • Властивості (у тому числі автоматичні)
  • Делегати
  • Події
  • Анонімні методи
  • Лямбда-вирази
  • Expression Trees
  • Анонімні класи
  • Потужний висновок типів
  • Перевантаження операторів
  • Indexers
  • …ще багато чого
Властивості C# представляють синтаксичний цукор, т.к. при компіляції перетворюються на методи типу GetXXX, SetXXX. Однак інформація про поняття властивість зберігається в метаданих, тому з будь-якої іншої підтримуючої властивості мови ми можемо звернутися до неї тільки як object.PropertyX, а не object.GetPropertyX.

Наприклад:

Public class TestClass (public int TotalSum (get (return Count * Price;)) // Автоматична властивість - компілятор сам згенерує поля public int Count (get; set;) public int Price (get (return 50;)))
Буде перетворено на вигляд:

Public class TestClass ( /* *весь інший код */ private int k__BackingField; //автоматична властивість - компілятор сам згенерує поля public int Count (get (return k__BackingField; ) set ( k__BackingField = value; ) ) )
Делегатиє аналогами покажчиків на методи C/C++. Проте є типобезпечними. Їхнє головне призначення – callback функції, а також робота з подіями.

У цьому делегати в.NET – повноцінні об'єкти.

Цей підхід докорінно відрізняється від проекту Da Vinci для Java, т.к. в останньому намагаються розширити саму VM.

Розглянемо приклад на C#:

Public class TestClass ( public delegate int BinaryOp(int arg1, int arg2); public int Add(int a, int b) ( return a + b; ) public int Multiply(int first, int second) public void TestDelegates() ( BinaryOp op = new BinaryOp(Add); int result = op(1, 2); Console.WriteLine(result); //виведе: 3 op = new BinaryOp(Multiply); , 5);Console.WriteLine(result); //виведе: 10)))
А також на C:

Int Add(int arg1, int arg2) ( return arg1 + arg2; ) void TestFP() ( int (*fpAdd)(int, int); fpAdd = //вказівник на функцію int three = fpAdd(1, 2); / / Викликаємо функцію через покажчик )
Отже, що ми бачимо? Якщо C ми можемо передати покажчик на функцію коїться з іншими типами параметрів (скажімо float arg1, float arg2), то C# - це неможливо. У C# делегати проходять як перевірку сигнатури і типів на етапі компіляції, а й у рантаймі.

Подіїнеобхідні реалізації подієво-орієнтованого програмування. Звичайно, можна обійтися і EventDispatcher'ом, або патерном Publisher/Subscriber. Однак нативна підтримка з боку мови надає вагомих переваг. Одним з яких є типобезпека.

Наприклад:

Public class MyClass ( private string _value; public delegate void ChangingEventhandler(string oldValue); public event ChangingEventhandler Changing; Value ( get ( return _value; ) set ( OnChanging(_value); _value = value; ) ) public void TestEvent() ( MyClass instance = new MyClass(); instance. "new string value"; //будет вызван метод instance_Changing } void instance_Changing(string oldValue) { Console.WriteLine(oldValue); } } !}
Анонімні методизначно спрощують життя – структура класу залишається чистої, тобто. не потрібно створювати окремі зайві методи у самому класі.

Змінимо наведений вище приклад з бінарними операціями з використанням анонімних методів:

Public class TestClass ( public delegate int BinaryOp(int arg1, int arg2); 1, 2);Console.WriteLine(result); //виведе: 3)))
Чи не правда коротше і чистіше?

Розглянемо тепер лямбда-вирази.

Лямбда-вираз - це анонімна функція, що містить вирази та оператори, а також може використовуватись для створення делегатів або дерева виразів.

Public class TestClass ( public delegate int BinaryOp(int arg1, int arg2); Console.WriteLine(result); // виведе: 3 ) )
А як виглядатиме приклад із подіями? Дуже просто:

Public class MyClass ( /* * весь інший код */ public void TestEvent() ( MyClass instance = new MyClass(); instance.Changing += (o) => Console.WriteLine(o); instance.Value = "(!) LANG:new string value"; //будет вызван Console.WriteLine } } !}
Що ж, ми скоротили код ще більше і це вже стає схожим на функціональний стиль (!!!). Так, C# є ще й функціональним мовою, т.к. Функції є об'єктами першого класу.

Лямбда-вирази, а разом з ними і дерева виразів були створені разом з LINQ(Language Integrated Query).

Все ще не знайомі з LINQ? Хочете побачити як виглядатиме знаменитий MapReduce на LINQ?

Public static class MyClass ( public void MapReduceTest() ( var words = new ("...some text goes here..."); var wordOccurrences = words .GroupBy(w => w) .Select(intermediate => new ( Word = intermediate.Key, Frequency = intermediate.Sum(w => 1) )) .Where(w => w.Frequency > 10) .OrderBy(w => w.Frequency); ) )
Або ж використовувати SQL-подібний синтаксис:

Public void MapReduceTest() ( string words = new string ( "...some text goes here..." ); intermediate.Sum((string w) => 1) )in w w where w.Frequency > 10 orderby w.Frequency select w; )
У цьому прикладі бачимо і LINQ (GroupBy().Select().Where() і т.д.), і анонімні класи –

New (Word = intermediate.Key, Frequency = intermediate.Sum(w => 1) )
Що ж ще тут використовується? Відповідь проста – потужна система виведення типів.

Головну роль тут відіграє ключове слово var. C++ 11 має аналогічну конструкцію auto.

Так без виведення типів нам довелося б писати так:

Public void MapReduceTest() ( string words = new string ( "...some text goes here..." ); var wordOccurrences = Enumerable.OrderBy(Enumerable.Where(Enumerable.Select(Enumerable.GroupBy) (words, delegate (string w) ( return w; )), delegate (IGrouping intermediate) ( return new ( Word = intermediate.Key, Frequency = Enumerable.Sum) (Intermediate, (Func ) (w => 1)) ); )), delegate (<>f__AnonymousType0 w) ( return w.Frequency > 10; )), delegate (<>f__AnonymousType0 w) (return w.Frequency; )); )
[Цей методзгенерував за нас компілятор]

Для опису решти можливостей C#, налаштувань його компілятора тощо. необхідно присвятити ще одну статтю.

А тим часом, C# 5 - який вже доступний і незабаром буде його офіційний реліз. асинхронне програмування, Що з'явилося також і C++ 11!

▌ Висновок

C# і Java є потужними мовами, і навіть потужними платформами (.NET і Java). Як я вже писав на початку статті – для кожного завдання існує свій інструмент.

C# - не є продовженням або копіювальним Java. Навіть коли він розроблявся в Microsoft, його кодова назва була COOL (C-like Object Oriented Language). Скільки разів у цій статті наводилася аналогія з C/C++? Достатня кількість.

Сподіваюся, що моя стаття допомогла вирішити (хоча б трохи) питання різниці і мов, і платформ.

Дякую за увагу!