Спор "Java vs. C#" существует чуть меньше, чем вечность. Есть много статей, затрагивающих разные участки его спектра: Что есть в C# чего нет в Java, что языки друг у друга позаимствовали, у одних LINQ, у других обратная совместимость, в общем, тысячи их.
Однако, я никогда не видел, чтобы писали о чём-то, что в Java, с точки зрения фич языка есть, чего в C# нет. Впрочем, я здесь не для того, чтобы спорить. Эта статья призвана выразить моё субъективное мнение и заполнить небольшой пробел по теме, озвученной в заголовке.
Оба языка крутые, востребованные, у меня нет цели принизить один на фоне другого. Наоборот, хочу озвучить, что можно было бы, на мой взгляд, привнести, и порассуждать о том, насколько это нужно. Поэтому перейдём сразу к списку.
1. Class based Enum
Ни для кого не секрет, что в отличие от Java, в C# и C++ перечисления это именованные числовые константы. А что есть перечисления в Java? По сути, синтаксический сахар поверх класса. Напишем какое-нибудь перечисление, например. для хранения типов "слов", распознаваемых лексическим анализатором:И поскольку перечисление это тот же класс, то можно накрутить конструктор, методы, поля, да даже реализацию интерфейса! Добавим возможность константам перечисления трансформироваться в регулярное выражение:
А как сделать подобное в C#? Есть два варианта:
- Атрибуты и методы расширений с рефлексией (нельзя реализовывать интерфейсы):
- Классы с публичными статическими константами:
Напрашивается вопрос:
Особенно актуальный при наличии новых возможностей языка в последних версиях относительно ключевого слова switch.Зачем мне перечисления в C#, если я могу реализовывать их так, как они устроены в Java?
2. Full support of covariant return types
Если раньше код писался примерно так:То сейчас лишние конструкции можно опустить:
В Java это было почти всегда, и сама возможность работала чуть шире. Она распространялась на реализацию и расширение интерфейсов. Например, я описываю структуру, которую можно копировать вместе данными. Для этого мне нужно указать, что данные копируются. За это отвечает контракт Cloneable. По умолчанию, метод clone возвращает Object. Однако, чтобы не засорять код кастами, я могу написать, что clone возвращает то, что копируется:
В C# так сделать нельзя, выйдет ошибка:
Method 'Clone' cannot implement method from interface 'System.ICloneable'. Return type should be 'object'.
Почему у интерфейсов ещё нет ковариантности возвращаемого типа - вопрос открытый, .
3. Functional Interfaces
В Java есть понятие функциональный интерфейс. Функциональный интерфейс (functional interface) – интерфейс с единственным абстрактным методом. Основная фишка таких интерфейсов в том, что их экземпляры можно инициализировать с помощью лямбда выражений (начиная с Java 8):Однако, о том, почему именно так всё устроено, нетрудно догадаться, если посмотреть, на что предлагает заменить IDE значение, присваиваемое переменной add типа IntegerBinaryExpression:
Если нажать на предлагаемый replace, то получим:
Всё это, вместе с синтаксисом "пуговицы" (::), говорит об одном: функциональные интерфейсы - всего лишь механизм реализации callback'ов в Java. В C# есть делегаты, поэтому надобность в подобном сахаре крайне сомнительна, хоть и выглядит удобно, особенно для интерфейсов, экземпляры которых используются в проекте единожды.
4. Anonymous interface implementation
Предыдущий пример, возможно, стоило рассмотреть именно в этой секции, поскольку он является демонстрацией частного случая крутой, на мой взгляд, фичи Java - анонимная реализация интерфейсов.Возьмём теперь контракт, у которого не меньше двух методов:
И если начать набирать new Pair для создания экземпляра интерфейса, то нам не выскочит ошибка о том, что нельзя создавать инстансы абстрактных сущностей, а предложение реализовать методы:
Также такие штуки можно проворачивать и с классами (
Эта фича открывает новые возможности для создания программного обеспечения в случаях, когда надо не раздувать структуру проекта и на лету создавать новые реализации контрактов, или необходимо инкапсулировать какие-то специфичные сценарии использования контракта. Безусловно, жду в C#, все возможности у CLR для этого есть. .
Заключение
Поделился с Вами о своих взглядах о возможных направлениях развития языка программирования C# и освятил, ранее не тронутую тему, о том, чего в C# нет, что в Java есть. Надеюсь, было интересно и полезно! Спасибо, что прочитали!Автор статьи: Stefanio