Книга: 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

Оглавление книги


Генерация: 1.740. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз