C# поддерживает "неровные" массивы и добавляет многомерные массивы. Может сбить с толку то, что Java не делает между ними различий:
int [] х = new int[20]; // как в Java, только [] должны следовать
// за типом
int [,] у = new int[12, 3]; // то же самое, что int у[] [] = new
// int[12][3];
int[][] z = new int[5][]; // то же самое, что и int x[][] = new
// int [5][];
Примечание.
Ключевое слово
int[]
обозначает реальный тип данных, поэтому синтаксически оно записывается таким образом. Нельзя, как в Java, поместить двойные скобки перед или после переменной. Прежде чем перейти к дополнительным деталям о ссылочных типах и обсуждению таких концепции, как классы, давайте поговорим немного об операциях. Следующий раздел посвящен операторам.
Операторы
В Java конечный результат применения оператора к одному или нескольким операндам является новым значением для одного или нескольких вовлеченных операндов. C# предоставляет аналогичную функциональность, однако, как можно будет увидеть в разделах ниже, существуют незначительные различия между C# и Java даже в этой области. В этом разделе мы охватим разные группы операторов в C# и обсудим чем отличается в C# и Java каждая группа.
Присваивание
C# и Java используют знак
=
для присваивания значений переменным. В C#, как и в Java, переменные присвоенные объектам содержат только ссылку или "адрес" на этот объект, а не сам объект. Присваивание одной ссылочной переменной другой таким образом просто копирует "адрес" в новую переменную. Следовательно обе переменные теперь имеют возможность делать ссылку на один объект. Эту концепцию легко проиллюстрировать с помощью примера. Рассмотрим класс
ExOperators
, приведенный ниже:
public class EXOperators {
internal int р;
public EXOperators {}
public static void Main {
ExOperators one = new EXOperators;
one.p = 200;
EXOperators two;
two = one;
two.p = 100;
Console.WriteLine(two.p);
Console.WriteLine(one.p);
}
}
Пока проигнорируем ключевое слово
internal
перед переменной
р
. Оно является модификатором доступа, который будет рассмотрен далее в этой главе. Достаточно сказать, что оно делает переменную
р
видимой для метода
Main
. Приведенный выше пример создает экземпляр объекта
EXOperators
и сохраняет его в локальной переменной
one
. Эта переменная затем присваивается другой переменной —
two
. После этого значение
p
в объекте, на который ссылается
two
, изменяется на 100. В конце выводится значение переменной
p
в обоих объектах. Компиляция и выполнение этого даст результат 100
дважды, указывая, что изменение
two.р
было тем же самым, что изменение значения
one.р
.
Сравнение
Операторы сравнения обычно совпадают по форме и функциональности в обоих языках. Четырьмя основными операторами являются
<
— меньше, чем,
>
— больше, чем,
<=
— меньше или равно и
>=
— больше или равно.
Чтобы определить, принадлежит ли объект заданному классу или любому из классов предков, Java использует оператор
instanceof
. Простой пример этого приведен в листинге ниже:
String у = "a string";
Object х = у;
if (х instanceof String) {
System.out.println("х is a string");
}
В C# эквивалентом
instanceof
является оператор
is
. Он возвращает
true
, если тип времени выполнения заданного класса совместим с указанным типом. Версия C# приведенного выше кода будет иметь следующую форму:
string у = "a string";
object х = у;
if (х is System.String) {
System.Console.WriteLine("x is a string");
}
Операторы равенства aрифметические, условные, побитовые, битового дополнения и сдвига
В обоих языках операторы равенства могут использоваться для тестирования чисел, символов, булевых примитивов, ссылочных переменных. Все другие операторы, упомянутые выше работают таким же образом.
Преобразование типов
Преобразование в Java состоит из неявного или явного сужения или расширения преобразования типа при использовании оператора
. Можно выполнить аналогичное преобразование типа в C#. C# также вводит ряд действенных способов, встроенных в язык, среди них мы выделим упаковку и распаковку.
Так как типы значений являются блоками памяти определенного размера, они прекрасно подходят для целей ускорения. Иногда, однако удобство объектов желательно иметь для типов значений. Упаковка и распаковка предоставляет механизм, который формирует линию соединения между типами значений и ссылочными типами, позволяя преобразовать их в и из объектного типа.
Упаковка объекта означает неявное преобразование любого типа значения в объектный тип. Экземпляр объекта создается и выделяется, а значение из типа значения копируется в новый объект. Здесь приведен пример, показывающий, как упаковка работает в C#: