Чтение онлайн

на главную - закладки

Жанры

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

Ватсон Карли

Шрифт:

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

Определенные пользователем преобразования типов данных

Так же как для индексаторов и

[]
, C# формально не рассматривает
как оператор, который может перезагружаться, однако C# допускает определяемые пользователем преобразования типов данных, которые имеют тот же результат. Например, предположим, что имеются два класса (или структуры) с именами
MySource
и
MyDest
и необходимо определить преобразование типа из
MySource
в
MyDest
. Синтаксис этого выглядит следующим образом:

public static implicite operator MyDest(MySource Source) {

 // код для выполнения преобразования. Должен возвращать экземпляр MyDest

}

Преобразование типа данных определяется как статический член класса

MyDest
или класса
MySource
. Оно должно также объявляться любо как
implicit
, либо как
explicit
. Если преобразование объявлено как
implicit
, то оно используется неявно:

MySource Source = new MySource;

MyDest Dest = MySource;

Если преобразование объявлено как explicit, то оно может использоваться только явным образом:

MySource Source = new MySource;

MyDest Dest = (MyDest)MySource;

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

Так же как и в C++, если компилятор C# встречается с запросом преобразования между типами данных, для которых не существует прямого преобразования типов, он будет стараться найти "лучший" способ, используя доступные методы преобразования типов. Существуют те же вопросы, что и в C++, в отношении интуитивной ясности преобразований типов данных, а также в том, что различные пути получения преобразования не создают несовместимых результатов.

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

Отметим, что если попробовать выполнить преобразование ссылки базового класса в ссылку производного класса, и при этом рассматриваемый объект не является экземпляром производного класса (или какого-нибудь производного из него), то будет порождаться (генерироваться) исключение. В C++ нетрудно преобразовать указатель на объект в "неправильный" класс объектов. Это просто невозможно в C# с помощью ссылок. По этой причине преобразование типов в C# считается более безопасным, чем в C++.

// пусть MyDerivedClass получен из MyBaseClass

MyBaseClass MyBase = new MyBaseClass;

MyDerivedClass MyDerived = (MyDerivedClass) MyBase; // это приведет

 // к порождению исключения

Если нежелательно преобразовывать что-то в производный класс, но нежелательно также, чтобы генерировалось исключение, можно применить ключевое слово

as
.
При использовании as, если преобразование отказывает, будет возвращаться
null
.

// пусть MyDerivedClass получен из MyBaseClass

MyBaseClass MyBase = new MyBaseClass;

MyDerivedClass MyDerived as (MyDerivedClass)MyBase; // это

// возвратит null

Массивы

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

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

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

System.Array
, но для этого понадобится использовать указатели и ненадежные блоки кода.

Одномерные массивы

Для одномерных массивов (терминология C#: массивы ранга 1) синтаксис доступа в обоих языках идентичен — с квадратными скобками, используемыми для индикации элементов массива. Массивы начинаются с нулевого индекса в обоих языках.

Например, чтобы умножить каждый элемент массива

float
на 2:

// массив, объявлен как массив float

// этот код работает в C++ и C# без каких-либо изменений

for (int i = 0; i < 10; i++) Array[i] = 2.0f;

Однако, как упоминалось ранее, массивы C# поддерживают свойство

Length
, которое используется для определения числа элементов в массиве.

// массив, объявлен как массив float

// этот код компилируется только в C#

for (int i = 0; i < Array.Length; i++) Array[i] *= 2.0f;

В C# можно также использовать инструкцию

foreach
для доступа к элементам массива, что рассматривалось ранее.

Синтаксис объявления массивов в C# слегка отличается, так как массивы C# всегда объявляются как ссылочные объекты.

double [] Array; // простое объявление ссылки без реального

// создания экземпляра массива

Array = new double[10]; // реально создается экземпляр объекта

// System.Array и задается размер 10.

Поделиться:
Популярные книги

Кодекс Крови. Книга ХVI

Борзых М.
16. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVI

Хозяйка забытой усадьбы

Воронцова Александра
5. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка забытой усадьбы

Ротмистр Гордеев

Дашко Дмитрий Николаевич
1. Ротмистр Гордеев
Фантастика:
фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев

Лисья нора

Сакавич Нора
1. Всё ради игры
Фантастика:
боевая фантастика
8.80
рейтинг книги
Лисья нора

Запрети любить

Джейн Анна
1. Навсегда в моем сердце
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Запрети любить

Мастер 9

Чащин Валерий
9. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 9

Магия чистых душ 2

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.56
рейтинг книги
Магия чистых душ 2

Кодекс Крови. Книга V

Борзых М.
5. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга V

Безумный Макс. Ротмистр Империи

Ланцов Михаил Алексеевич
2. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
4.67
рейтинг книги
Безумный Макс. Ротмистр Империи

Возрождение Феникса. Том 2

Володин Григорий Григорьевич
2. Возрождение Феникса
Фантастика:
фэнтези
попаданцы
альтернативная история
6.92
рейтинг книги
Возрождение Феникса. Том 2

Ты - наша

Зайцева Мария
1. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Ты - наша

(не) Желанная тень его Высочества

Ловиз Мия
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
(не) Желанная тень его Высочества

Господин моих ночей (Дилогия)

Ардова Алиса
Маги Лагора
Любовные романы:
любовно-фантастические романы
6.14
рейтинг книги
Господин моих ночей (Дилогия)

Возвышение Меркурия. Книга 12

Кронос Александр
12. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 12