В чем отличие c от java. Расположение исходного текста в файлах

22.03.2019

Синтаксис

Оба языка используют в качестве синтаксической основы язык программирования 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#. Он показан некорректно из за технических ограничений. 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 = new ArrayList(); List intList = new ArrayList(); bool areSame = strList.getClass() == intList.getClass(); System.out.println(areSame);
Выведет true .

При этом вместо обобщенного типа T создается экземпляр объекта типа java.lang.Object .

List strList = new ArrayList(); strList.add("stringValue"); String str = strList.get(0);
Будет преобразован к виду:

List list = new 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 = new ArrayList();
Но нельзя так:

List intList = new 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 = &point; p->x = 100; p->y = 200; Point point2; Point* p2 = &point2; (*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) { return first * second; } public void TestDelegates() { BinaryOp op = new BinaryOp(Add); int result = op(1, 2); Console.WriteLine(result); //выведет: 3 op = new BinaryOp(Multiply); result = op(2, 5); Console.WriteLine(result); //выведет: 10 } }
А также на C:

Int Add(int arg1, int arg2) { return arg1 + arg2; } void TestFP() { int (*fpAdd)(int, int); fpAdd = &Add; //указатель на функцию 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; public void OnChanging(string oldvalue) { ChangingEventhandler handler = Changing; if (handler != null) handler(oldvalue); } public string Value { get { return _value; } set { OnChanging(_value); _value = value; } } public void TestEvent() { MyClass instance = new MyClass(); instance.Changing += new ChangingEventhandler(instance_Changing); instance.Value = "new string value"; //будет вызван метод instance_Changing } void instance_Changing(string oldValue) { Console.WriteLine(oldValue); } }
Анонимные методы существенно упрощают жизнь – структура класса остается чистой, т.е. не нужно создавать отдельные лишние методы в самом классе.

Изменим вышеприведенный пример с бинарными операциями с использованием анонимных методов:

Public class TestClass { public delegate int BinaryOp(int arg1, int arg2); public void TestDelegates() { BinaryOp op = new BinaryOp(delegate(int a, int b) { return a + b; }); int result = op(1, 2); Console.WriteLine(result); //выведет: 3 } }
Не правда ли более коротко и чисто?

Рассмотрим теперь лямбда-выражения .

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

Public class TestClass { public delegate int BinaryOp(int arg1, int arg2); public void TestDelegates() { BinaryOp op = new BinaryOp((a, b) => a + b); int result = op(1, 2); Console.WriteLine(result); //выведет: 3 } }
А как же будет выглядеть пример с событиями? Очень просто:

Public class MyClass { /* * весь остальной код */ public void TestEvent() { MyClass instance = new MyClass(); instance.Changing += (o) => Console.WriteLine(o); instance.Value = "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..." }; var wordOccurrences = from w in words group w by w into intermediate select new { Word = intermediate.Key, Frequency = intermediate.Sum((string w) => 1) } into 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++? Достаточное количество.

Надеюсь, что моя статья помогла решить (хотя бы немного) вопрос разности и языков, и платформ.

Спасибо за внимание!