Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек_ООП_2_1_1 Синтаксис языка C#. Данные и опе...doc
Скачиваний:
2
Добавлен:
13.11.2019
Размер:
208.9 Кб
Скачать

Почему в c# типы данных являются одновременно и классами?

В C# все типы – встроенные и пользовательские - одновременно являются классами, связанными отношением наследования.

Родительским, базовым классом является класс Object. Все остальные типы или, точнее, классы являются его потомками, наследуя методы этого класса.

У класса Object есть четыре наследуемых метода:

1. bool Equals(object obj) - проверяет эквивалентность текущего объекта и объекта, переданного в качестве аргумента;

2. System.Type GetType() - возвращает системный тип текущего объекта;

3. string ToString() - возвращает строку, связанную с объектом. Для арифметических типов возвращается значение, преобразованное в строку;

4. int GetHashCode() - служит как хэш-функция в соответствующих алгоритмах поиска по ключу при хранении данных в хэш-таблицах.

Примеры объявления переменных и присваивания им значений:

int x=11; // как значимый тип

int v = new Int32(); // как объект, значение 0 - по умолчанию

v = 007; // как значимый тип, присваивается значение 7

string s1 = "Agent";// как объект, ссылка на константную строку "Agent" в памяти

s1 = s1 + v.ToString() +x.ToString();// v и x как объекты

При каких условиях переменным одного типа можно присваивать значения другого типа?

Чтобы присваивание было допустимым, типы должны быть согласованными.

Для оператора X=Y; где X типа TX, а Y типа TY присваивание допустимо, если:

- либо в классе TY или его предке определена функция преобразования в тип TX;

- либо класс TY является потомком класса TX, но не наоборот.

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

Второе условие характерно для классов, создаваемых пользователем, и для класса Object. Его переменным можно присваивать значения любых типов, так как это предок всех классов. После такого присваивания переменная класса Object приобретает текущий тип в соответствии с типом присвоенного значения.

Заметим, что в C# нельзя перегружать оператор присваивания.

Функция преобразования в тип TX из типа TY может быть определена только в том случае, если TX и TY не связаны отношением наследования.

ВОПРОС К АУДИТОРИИ

Почему нельзя переменной – потомку присвоить значение переменной – родителя?

Почему можно делать наоборот?

Заметим, что если TX и TY классы, согласованные по присваиванию, то оператор X=Y; просто переставляет ссылку X на область памяти, занимаемую переменной Y. Так что «лишние» поля хоть и не используются предком, но и не исчезают из памяти. Их можно «вернуть обратно» с помощью явного преобразования типа. Например, допустим оператор Y =(TY)X;

Поле a

Поле b

Поле c

Поле d

Что из этого следует?

- Переменные класса Object можно использовать для временного хранения любых значений, которые можно извлекать из них с помощью явного преобразования типа.

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

Совет Как скопировать элементы массива m2 в массив m1

m2.CopyTo(m1,n); //Переписывает все элементы из m2 в m1, начиная с позиции n в m1. // Чтобы это работало, в m1 должно быть достаточно места.

Для многомерных массивов можно воспользоваться статическим методом Copy(m2,m1) класса Array.

Совет Как скопировать строку s2 в строку s1

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

s1 = String.Copy(s2); //Создает копию s2 и присваивает ее адрес s1

s1 = s2.Substring(2,5); //Создает копию подстроки s2 и присваивает ее адрес s1

Совет Как скопировать объект в объект

Если копируются экземпляры одного класса или связанные наследованием, то оператор присваивания переустанавливает ссылку. Поэтому придется в этом классе запрограммировать функцию (например, свойство с именем Val). Эта функция должна создать новый объект, переписать в него все требуемые поля и вернуть ссылку на него.

Если копируются экземпляры различных классов, не связанных наследованием, то оператор присваивания вызывает функцию преобразования типа, определенную в классе присваиваемого типа.

Функция преобразования из типа TY в тип TX может быть определена только в том случае, если TX и TY не связаны отношением наследования. Она задается в классе TY следующим образом: public static implicit operator TX(TY y) { return ; }