Все классы и типы наследуются от object
. Кроме того, это зависит от того, из какого класса происходит другой класс. Используя это, компилятор может определить, может ли что-то быть приведено от одного к другому. Некоторые из этих проверок могут быть определены во время компиляции, а некоторые во время выполнения.
Рассмотрим:
class A
class B
class C
class D
class E
Теперь, дайте ссылку на E
, я могу спокойно привести к D
или A
(или object
). Компилятор может сказать, что если я попытаюсь привести E
к C
или B
, преобразование не будет доступно, потому что E
не наследуется от этих 2, хотя они имеют общий базовый класс A
.
Теперь рассмотрим, есть ли у меня ссылка на A
, и попытайтесь привести к E
. Эта проверка не может быть выполнена во время компиляции и завершится неудачей во время выполнения, если рассматриваемый экземпляр на самом деле не является экземпляром E
(как, возможно, это может быть любой из 'A, B, C, D или E').
В дополнение к этому, как указывает Silvermind, мы можем предоставить наши собственные преобразования implicit
и explicit
там, где их нет. Учтите это:
public class Person
{
private string name_;
public Person(string name)
{
name_ = name;
}
// allow conversion to a string
public static implicit operator string(Person p)
{
return p.name_;
}
}
Вышесказанное позволяет нам идти:
Person p = new Person("Moo-Juice");
string name = (string)p;
Без нашего неявного оператора это (очевидно) завершится с ошибкой во время компиляции, поскольку по умолчанию преобразование не выполняется из Person
в string
.
Явные операторы похожи, но работают иначе. Это происходит, если мы хотим привести строку к person . Таким образом, мы могли бы добавить следующий явный оператор:
public static explicit operator Person(string name)
{
return new Person(name);
}
И теперь мы можем сделать это:
string name = "Moo-Juice";
Person p = (Person)name;