KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Симон Робинсон - C# для профессионалов. Том II

Симон Робинсон - C# для профессионалов. Том II

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Симон Робинсон, "C# для профессионалов. Том II" бесплатно, без регистрации.
Перейти на страницу:

Параметры методов

Как и в C++, по умолчанию параметры передаются в методы по значению. Если требуется это изменить, можно использовать ключевое слово ref, указывающее, что параметр передается по ссылке, и out, чтобы указать, что это параметр вывода (всегда передается по ссылке). Если это сделано, то необходимо объявлять этот факт как в определении метода, так и при его вызове.

public void MultiplyByTwo(ref double d, out double square) {

 d *= 2;

 square = d*d;

}


// позже, при вызове метода

double Value, Square Value = 4.0;

MultiplyByTwo(ref Value, out Square);

Передача по ссылке означает, что метод может изменять значение параметра. Передача по ссылке также осуществляется, чтобы улучшить производительность при работе с большими структурами, также как и в C++, передача по ссылке означает, что копируется только адрес. Отметим, однако, что, если при передаче по ссылке из соображений производительности вызываемый метод по-прежнему не изменяет значения параметра, то C# не разрешает присоединять модификатор const к параметрам, как это делает C++.

Параметры типа out действуют по большей части так же, как ссылочные параметры. Но они предназначены для случаев, когда вызываемый метод задает значение для параметра, а не изменяет его. Следовательно, инициализации параметров будут отличаться. C# требует, чтобы параметр ref инициализировался внутри вызываемого метода до своего использования.

Перезагрузка методов

Методы могут быть перезагружены таким же образом, как в C++. Однако C# не допускает в методах параметров по умолчанию. Это можно смоделировать с помощью перезагружаемой версии:

Для C++ можно сделать следующую запись:

double DoSomething(int someData, bool Condition=true) {

 // и т.д.

В то время как в C# необходимо выполнить такие действия:

double DoSomething(int someData) {

 DoSomething(someData, true);

}

double DoSomething(int someData, bool condition) {

 // и т.д.

Свойства

Свойства не имеют эквивалента в ANSI C++, хотя они были введены как расширение в Microsoft Visual C++. Свойство является методом или парой методов, которые синтаксически оформлены для представления в вызывающем коде, как будто свойство является полем. Они существуют для ситуации, когда интуитивно удобнее вызывать метод с помощью синтаксиса поля, очевидным примером будет случай закрытого поля, которое должно быта инкапсулировано с помощью оболочки из открытых методов доступа. Предположим, что класс имеет такое поле length типа int. Тогда в C++ оно инкапсулируется с помощью методов GetLength() и SetLength(). Необходимо будет обращаться к нему извне класса:

// MyObject является экземпляром рассматриваемого класса

MyObject.SetLength(10);

int Length = MyObject.GetLength();

В C# можно реализовать эти методы, как аксессоры (методы доступа) get и set свойства Length. Тогда запишем

// MyObject является экземпляром рассматриваемого класса

MyObject.Length = 10;

int length = MyObject.Length;

Чтобы определись эти методы доступа, свойство будет определяться следующим образом:

class MyClass {

 private int length;

 public int Length {

  get {

   return length;

  }

  set {

   Length = value;

  }

Хотя методы доступа get и set реализованы здесь, чтобы просто возвращать или задавать поле length, в эти методы можно поместить любой другой требуемый код C# так же, как это обычно делается в методе. Например, добавить некоторую проверку данных в метод доступа set. Отметим, что метод доступа set возвращает void и получает дополнительный неявный параметр с именем value.

Можно опустить любой из методов доступе get или set из определения свойства, и в этом случае свойство осуществляет соответственно либо только запись, либо только чтение.

Операторы

Значение и синтаксис операторов в большинстве случаев те же в C#, что и в C++. Следующие операторы по умолчанию имеют в C# такое же значение и синтаксис как и в C++:

□ Бинарные арифметические операторы +, -, *, /, %

□ Соответствующие арифметические операторы присваивания +=, -=, *=, /=, %=

□ Унарные операторы ++ и -- (обе — префиксная и постфиксная формы)

□ Операторы сравнения !=, ==, <, <=, >=

□ Операторы сдвига >> и <<

□ Логические операторы &, |, &&, ||, ~, ^, !

□ Операторы присваивания, соответствующие логическим операторам: >>=, <<=, &=, |=, ^=

□ Тернарный (условный) оператор

Символы (), [], и , (запятая) также имеют в общих чертах такой же эффект в C#, как и в C++.

Необходимо быть осторожным со следующими операторами, так как они действуют в C# иначе, чем в C++:

□ Присваивание (=), new, this.

Оператор разрешения области видимости в C# представлен ., а не :: (:: не имеет смысла в C#). Также в C# не существуют операторы delete и delete[]. Они не нужны, так как сборщик мусора автоматически управляет очисткой памяти в куче. Однако C# предоставляет также три других оператора, которые не существуют в C++, а именно, is, as и typeof. Эти операторы связаны с получением информации о типе объекта или класса.

Оператор присваивания (=)

Для простых типов данных = просто копирует данные. Однако при определении своих собственных классов C++ считает в большой степени, что обязанность разработчика указать значение = для этих классов. По умолчанию в C++ = требует поверхностного почленного копирования всех переменных, классов или структур. Однако программисты перезагружают этот оператор для выполнения более сложных операций присваивания.

В C# правила, определяющие, что означает оператор присваивания, значительно проще. Вообще не разрешается перезагружать =, его значение неявно определено во всех ситуациях.

Ситуация в C# будет следующая:

□ Для простых типов данных = просто копирует значения, как в C++.

□ Для структур = делает поверхностное копирование структуры — прямую копию памяти данных в экземпляре структуры. Это аналогично поведению в C++.

□ Для классов = копирует ссылку, то есть адрес, а не объект. Это не соответствует поведению в C++.

Если требуется скопировать экземпляры классов, обычный способ в C# состоит в переопределении метода MemberwiseCopy(), который все классы в C# по умолчанию наследуют из класса System.Object — общего класса-предка, из которого неявно выводятся все классы C#.

this

Оператор this имеет то же самое значение, что и в C++, но это скорее ссылка, а не указатель. Например, в C++ можно записать:

this->m_MyField = 10;

В C# это будет выглядеть так:

this.MyField = 10;

this используется в C# таким же образом, как и в C++. Например, можно передавать его в качестве параметра в вызовах методов или использовать его, чтобы сделать явным доступ к полю-члену класса. В C# существует пара других ситуаций, которые синтаксически требуют использования this, о них будет упомянуто в разделе о классах.

new

Как сообщалось ранее, оператор new, интерпретируемый как конструктор, имеет другое значение в C#, поскольку он обеспечивает инициализацию объекта а не запрос динамического выделения памяти.

Классы и структуры

В C++ классы и структуры очень похожи. Формально единственное различие состоит в том, что члены структуры являются по умолчанию открытыми, в то время как члены класса являются по умолчанию закрытыми. На практике, однако, многие программисты предпочитают использовать структуры и классы различным образом, сохраняя использование структур для объектов данных, которые содержат только члены-переменные (другими словами, без функций членов или явных конструкторов).

C# отражает это традиционное различие использования. В C# класс — это совершенно другой тип объектов, по сравнению со структурой, поэтому нет необходимости тщательно рассматривать, будет ли лучше определить заданный объект как класс или как структуру. Наиболее важные различия между классами C# и структурами C# следующие:

□ Структуры не поддерживают наследование, кроме того факта, что они являются производными из System.ValueType. Невозможно наследовать от структуры и структура не может наследовать от другой структуры или класса.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*