Вход/Регистрация
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:

  • Читать дальше
  • 1
  • ...
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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