Как компилятор решает, может ли тип быть приведен к другому типу - PullRequest
0 голосов
/ 16 марта 2012

На прошлой неделе я выполнил приведение некоторых объектов (приведение элементов управления DataGridView Columns) и попытался преобразовать столбец DataGridView TextBox в элемент управления TextBox, где произошла ошибка времени компиляции.

Я обнаружил, что должен выполнить приведение этогоTextBox Column to DataGridViewTextBoxColumn.

Так как же компилятор решает, может ли тип быть приведен к другому типу (в основном объектам)?

Далее у вас есть случаи, когда компилятор позволяет вам выполнять некоторые приведенияно вы получите ошибку во время выполнения.

1 Ответ

5 голосов
/ 16 марта 2012

Все классы и типы наследуются от 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...