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

Bur*_*imi 0 c# compiler-construction casting object

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

我发现我应该将TextBox Column强制转换为DataGridViewTextBoxColumn.

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

接下来,您将遇到编译器允许您执行某些强制转换的情况但会出现运行时错误.

Moo*_*ice 5

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

考虑:

class A
    class B
    class C
    class D
        class E
Run Code Online (Sandbox Code Playgroud)

现在,给出一个参考E,我可以安全地转换为DA(或object).编译器可以告诉大家,如果我尝试并投ECB没有转化为可用的,因为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_;
    }
}
Run Code Online (Sandbox Code Playgroud)

以上允许我们去:

Person p = new Person("Moo-Juice");
string name = (string)p;
Run Code Online (Sandbox Code Playgroud)

如果没有我们的内隐操作,这会(显然)在编译时失败,因为没有转换,从存在Personstring默认.

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

public static explicit operator Person(string name)
{
    return new Person(name);
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以这样做:

string name = "Moo-Juice";
Person p = (Person)name;
Run Code Online (Sandbox Code Playgroud)