Наверное, все знают, что C# - это мощный язык от великой и могучей компании зла добра Microsoft. Злые языки утверждают, что C# - это просто плохо спроектированная Java, но как же это впечатление обманчиво .
Да, C# был спроектирован под влиянием Java и многие архитектурные решения были взяты оттуда.
Да, код C# выглядит как код Java с нарушением конвенций об именовании.
Тем не менее, если вы Java-разработчик, не впадайте в иллюзию из-за схожести этих двух языков, иначе вас ждут очень странные и неочевидные ошибки, о некоторых из которых я и хочу поговорить.
То есть правильный вариант выглядит приблизительно так:
Microsoft, видимо, понимает некоторую проблему с пониманием этой таблички, поэтому в помощь к ней предлагает еще такую:
Если суммировать все вышенаписанное, то можно сказать:
И многое многое другое...
Да, C# был спроектирован под влиянием Java и многие архитектурные решения были взяты оттуда.
Да, код C# выглядит как код Java с нарушением конвенций об именовании.
Тем не менее, если вы Java-разработчик, не впадайте в иллюзию из-за схожести этих двух языков, иначе вас ждут очень странные и неочевидные ошибки, о некоторых из которых я и хочу поговорить.
Сравнение строк
Казалось бы, что может быть проще, чем простое сравнение двух строк на равенство. В Java есть метод Object#equals, который прекрасно решает эту задачу:
String a = ...;
String b = ...;
//как-то так
boolean eq1 = a.equals(b);
Используя свой опыт разработки, Java-разработчик, программируя на C#, с радостью обнаруживает метод Equals и пишет что-то подобное:
string a = ...;
string b = ...;
//большая ошибка...
bool eq1 = a.Equals(b);
и может совершить тем самым очень неочевидную ошибку.
Если мы воспользуемся в Visual Studio статическим анализатором кода Microsoft FxCop, то он нам любезно выдаст предупреждение:The behavior of 'string.Equals(string)' could vary based on the current user's locale settings.
Replace this call in with a call to 'string.Equals(string, System.StringComparison)'.
Анализатор говорит нам, что поведение метода string.Equals(string) может зависеть от настроек пользователя и предлагает воспользоваться методом string.Equals(string, System.StringComparison).
То есть правильный вариант выглядит приблизительно так:
string a = ...;
string b = ...;
bool eq1 = a.Equals(b, StringComparison.Ordinal);
Второй аргумент метода string.Equals(string, System.StringComparison) может принимать следующие значения:Название константы | Назначение |
---|---|
CurrentCulture | Сравнивать строки, используя правила сортировки с учетом языка и региональных параметров и текущий язык и региональные параметры. |
CurrentCultureIgnoreCase | Сравнивать строки, используя правила сортировки с учетом языка и региональных параметров и текущий язык и региональные параметры без учета регистра сравниваемых строк. |
InvariantCulture | Сравнивать строки, используя правила сортировки с учетом языка и региональных параметров и инвариантный язык и региональные параметры. |
InvariantCultureIgnoreCase | Сравнивать строки, используя правила сортировки с учетом языка и региональных параметров и инвариантный язык и региональные параметры без учета регистра сравниваемых строк. |
Ordinal | Сравнивать строки, используя правила обычной (двоичной) сортировки. |
OrdinalIgnoreCase | Сравнивать строки, используя правила обычной (двоичной) сортировки без учета регистра сравниваемых строк. |
Microsoft, видимо, понимает некоторую проблему с пониманием этой таблички, поэтому в помощь к ней предлагает еще такую:
Данные | Поведение | StringComparison |
---|---|---|
Внутренние идентификаторы с учетом регистра | Нелингвистические идентификаторы с точным соответствием байтов. | Ordinal |
Идентификаторы с учетом регистра в таких стандартах, как XML и HTTP | ||
Параметры безопасности с учетом регистра | ||
Внутренние идентификаторы без учета регистра | Нелингвистические идентификаторы с точным соответствием байтов. | OrdinalIgnoreCase |
Идентификаторы без учета регистра в таких стандартах, как XML и HTTP | ||
Пути к файлам | ||
Ключи реестра и значения | ||
Переменные среды | ||
Идентификаторы ресурсов (например, имена дескрипторов) | ||
Параметры безопасности без учета регистра | ||
Некоторые сохраненные лингвистически релевантные данные | Лингвистически релевантные данные без учета языка и региональных параметров | InvariantCulture InvariantCultureIgnoreCase |
Отображение лингвистических данных, требующее фиксированного порядка сортировки | ||
Данные, отображаемые пользователю | Пользовательский ввод в большинстве случаев | CurrentCulture CurrentCultureIgnoreCase |
Отображение лингвистических данных, требующее фиксированного порядка сортировки |
Если суммировать все вышенаписанное, то можно сказать:
Задача | На C# | На Java |
---|---|---|
Просто сравнить 2 строки |
|
|
Просто сравнить 2 строки без учета регистра |
|
|
Странные задачи, когда нужно считать, что строки "encyclopædia" и "encyclopaedia" равны |
|
??? |
Странные задачи, когда нужно считать, что строки "encyclopædia" и "encyclopaedia" равны |
|
??? |
Другие особенности
Работа со временем всегда была головной болью программистов. Занятно почитать, например, историю о человеке, который участвовал в большом распределенном проекте и его мысли о том, что класс Date в Java - это позор)).
Но вернемся к C#.
Из-за того, что сравнение строк - дело темное, это всплывает в неожиданных местах, например:
Из-за того, что сравнение строк - дело темное, это всплывает в неожиданных местах, например:
Неправильно на C# | Правильно C# | На Java |
---|---|---|
|
|
|
|
|
|
|
|
|
И многое многое другое...
Заключение
Итак, не впадайте в иллюзию, что знание Java автоматически дарует вам глубокое понимание языка C#.
При всей своей внешней схожести, языки различны по своим ценностным установкам, подходам и т.п.
Там, где Java опирается на комьюнити и сторонние библиотеки, C# будет опираться на богатые возможности языка и экосистему разработки. И нельзя сказать, кто из них двигается единственно верным путем.
Поэтому учите оба языка программирования (и еще Javascript, конечно), чтобы ваши руки были свободными, мнение непредвзятым, а носки поглаженными).
Удачи!
Комментариев нет:
Отправить комментарий