编译器如何确定Type是否可以转换为其他类型

时间:2012-03-16 07:54:39

标签: c# object compiler-construction casting

上周我处理了一些对象转换(DataGridView Columns Control转换),我尝试将DataGridView TextBox列转换为TextBox Control,我遇到了编译时错误。

我发现我应该将TextBox列转换为DataGridViewTextBoxColumn。

那么编译器如何决定是否可以将类型转换为其他类型(主要是对象)?

接下来,你有一些情况,编译器允许你做一些演员表,但你会得到一个运行时错误。

1 个答案:

答案 0 :(得分:5)

所有类和类型都继承自object。除此之外,它取决于另一个类派生的类。使用它,编译器可以确定是否可以从一个转换为另一个。其中一些检查可以在编译时确定,有些则在运行时确定。

考虑:

class A
    class B
    class C
    class D
        class E

现在,提供E的引用,我可以安全地转换为DA(或object)。编译器可以告诉我,如果我尝试将E强制转换为CB,则无法进行任何转换,因为E不会继承这些2,尽管它们共享一个共同点基类A

现在,请考虑我是否有A的引用,并尝试强制转换为E。如果有问题的实例实际上不是E的实例,那么这个检查不能在编译时执行,并且会在运行时失败(可以想象,它可以是'A,B,C,D或E'中的任何一个)。

除此之外,正如Silvermind所指出的,我们可以提供我们自己的implicitexplicit次转化。考虑一下:

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;

没有我们的隐式运算符,这显然会在编译时失败,因为默认情况下从Personstring不存在转换。

显式运算符类似,但以另一种方式工作。如果我们想将字符串强制转换为 person ,就会发生这种情况。所以我们可以添加以下显式运算符:

public static explicit operator Person(string name)
{
    return new Person(name);
}

现在我们可以这样做:

string name = "Moo-Juice";
Person p = (Person)name;