Книга: 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
- Преобразования типов
- Резервное копирование базы данных InterBase
- Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Резервное копирование многофайловых баз данных
- Восстановление из резервных копий многофайловых баз данных
- Владелец базы данных
- ЧАСТЬ IV. База данных и ее объекты.
- Перевод базы данных InterBase 6.x на 3-й диалект
- Типы данных для работы с датой и временем
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Обзор основных причин повреждения базы данных
- Ошибки проектирования базы данных