Ключевое слово "new" в языке C# в зависимости от контекста используется по-разному. Оно может задавать модификатор метода или операцию в выражениях. Операция new предназначена для создания объектов. Поскольку каждая реальная программа немыслима без объектов, операция new встречается практически во всех программах, хотя зачастую в неявной форме. Синтаксически эта операция имеет вид:
new <вызов конструктора объекта>
Чаще всего эта операция встречается в инициализаторах объекта в момент его объявления. Но допустимы и другие способы применения этой операции, скажем, в качестве фактического аргумента при вызове метода класса. Приведу совсем экзотический пример, где new встречается в арифметическом выражении:
Это объявление можно рассматривать как краткую форму записи следующих операторов:
int x = new int(); x = 77;
Операция sizeof возвращает заданный в байтах размер памяти, отводимой для хранения экземпляра класса. Ее единственным аргументом является имя класса. Существенное ограничение состоит в том, что она не применима к классам, создаваемым программистом.
Операция typeof возвращает объект класса Type, характеризующий тип класса, заданного в качестве аргумента операции. В отличие от операции sizeof она применима к классам, создаваемым программистом. Тот же результат, что и операция typeof, дает метод GetType, вызванный объектом - экземпляром класса. Этот метод наследуется от родительского класса object и существует у всех классов, в том числе и создаваемых программистом.
Приведу пример использования этих операций:
/// <summary>/// определение размеров и типов/// </summary>public void SizeMethod(){ Console.WriteLine("Размер типа Boolean = " + sizeof(bool)); Console.WriteLine("Размер типа double = " + sizeof(double)); Console.WriteLine("Размер типа char = " + sizeof(System.Char)); //Console.WriteLine("Размер класса TestingExpressoins = " + // sizeof(TestingExpressions)); int b1 = 1; Console.WriteLine("Тип переменной int b1: {0}, {1}", b1.GetType(), typeof(int)); Console.WriteLine("Тип класса TestingExpressoins = {0}", typeof(TestingExpressions)); }//SizeMethod
В этом примере операция применяется к трем встроенным типам - bool, double, char. Попытка применить эту операцию к собственному классу приводит к ошибке компиляции и потому закомментирована.
Операция typeof с успехом применена как к собственному классу TestingExpressions, так и к встроенному классу int.
На рис. 3.1 приведены результаты вывода на консоль, полученные при вызове этого метода.
Рис. 3.1. Результаты выполнения операций sizeof и typeof
1.5.6. Операции "увеличить" и "уменьшить" (increment, decrement)
Операции "увеличить на единицу" и "уменьшить на единицу" могут быть префиксными и постфиксными. В справочной системе утверждается, что к высшему приоритету относятся постфиксные операции x++ и x--, это нашло отражение в таблице 3.1.Префиксные операции имеют на единицу меньший приоритет.
В качестве результата обе операции возвращают значение переменной x. Главной особенностью как префиксных, так и постфиксных операций является побочный эффект, в результате которого значение x увеличивается (++) или уменьшается (--) на единицу. Для префиксных (++x, --x) операций результатом их выполнения является измененное значение x, постфиксные операции возвращают в качестве результата операции значение x до изменения. Префиксные операции вначале изменяют x, а затем возвращают результат. Постфиксные операции возвращают значение, а потом изменяют саму переменную. Приведу пример применения этих операций:
public void IncDec() { int n = 1, m = 0; Console.WriteLine("n = {0}", n); m = n++ + ++n; Console.WriteLine("m = n++ + ++n = {0},n = {1}", m, n); m = n++ + n + ++n; Console.WriteLine("m = n++ + n + ++n = {0},n = {1}", m, n); m = ++n + n + n++; Console.WriteLine("m = ++n + n + n++ = {0},n = {1}", m, n); }
Обратите внимание: хотя у постфиксной операции высший приоритет, это вовсе не означает, что при вычислении выражений вначале выполняются все постфиксные операции, затем все префиксные, и только потом будет проводиться сложение. Нет, вычисления проводятся в том порядке, в котором они написаны. Префиксные и постфиксные операции выполняются тогда, когда нужно вычислить соответствующий операнд.
Консольный вывод выполнения этого метода дает результат, показанный на рис. 3.2.
Рис. 3.2. Результат выполнения метода IncDec
Следует также заметить, что рассматриваемые операции применимы только к переменным, свойствам и индексаторам класса, то есть к выражениям, которым отведена область памяти. В языках C++ и C# такие выражения называются l-value, поскольку они могут встречаться в левых частях оператора присваивания. Как следствие, запись в C# выражения < --x++ > приведет к ошибке. Как только к x слева или справа приписана одна из операций, выражение перестает принадлежать к классу l-value выражений и вторую операцию приписать уже невозможно.
Подводя итоги, отмечу, что операции выполняются только тогда, когда вычисляется соответствующий операнд, а не в соответствии с приоритетом, указанным в таблице 3.1. Важнее помнить, что хороший стиль программирования рекомендует использовать эти операции только в выражениях, не содержащих других операндов. Еще лучше вообще не использовать их в выражениях, а применять их только как операторы:
x++; y--;
В этом случае фактически исчезает побочный эффект, являющийся опасным средством, и операции используются как краткая запись операторов: