简体   繁体   English

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

[英]How does compiler decide if a Type can be cast to another type

Last week I handled some object casting (DataGridView Columns Control casts) and I tried to cast a DataGridView TextBox Column to TextBox Control where I had a compile time error. 上周,我处理了一些对象强制转换(DataGridView Columns Control强制转换),并且尝试将DataGridView TextBox Column强制转换为TextBox控件,其中发生了编译时错误。

I found out that I should cast that TextBox Column to DataGridViewTextBoxColumn. 我发现应该将TextBox Column强制转换为DataGridViewTextBoxColumn。

So how does the compiler decide if a type can be cast to another type (objects mostly)? 那么,编译器如何确定一个类型是否可以强制转换为另一个类型(主要是对象)?

Next you have cases where the compiler lets you to do some casts but you will get a run time error. 接下来,您会遇到一些情况,编译器允许您进行一些强制转换,但会遇到运行时错误。

All classes and types inherit from object . 所有类和类型都从object继承。 Beyond that, it depends what class another class derives from. 除此之外,还取决于另一个类从哪个类派生。 Using this, the compiler can determine if something can be cast from one to another. 使用此功能,编译器可以确定是否可以将某些内容从一个对象投射到另一个对象。 Some of these checks can be determined at compile-time, and some at run-time. 这些检查中的一些可以在编译时确定,而另一些可以在运行时确定。

Consider: 考虑:

class A
    class B
    class C
    class D
        class E

Now, give a reference to E , I can safely cast to D or A (or object ). 现在,提供对E的引用,我可以安全地强制转换为DA (或object )。 The compiler can tell that if I try and cast E to C or B no conversion is available, because E does not inherit from these 2, though they share a common base-class of A . 编译器可以告诉大家,如果我尝试投ECB没有转化为可用的,因为E没有从这些2继承,但他们都有一个共同的基类的A

Now, consider if I have a reference to A and attempt to cast to E . 现在,考虑我是否引用A并尝试转换为E This check cannot be performed at compile time and will fail at runtime if the instance in question is not actually an instance of E (as, conceivably, it could be any of 'A, B, C, D or E'). 如果所讨论的实例实际上不是E的实例(例如,可以是'A,B,C,D或E'中的任何一个),则此检查不能在编译时执行,并且将在运行时失败。

In addition to this, as Silvermind points out, we can provide our own implicit and explicit conversions where none exist. 除此之外,正如Silvermind指出的,我们可以提供不存在的implicitexplicit转换。 Consider this: 考虑一下:

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_;
    }
}

The above allows us to go: 以上内容使我们可以:

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

Without our implicit operator, this would (obviously) fail at compile time as no conversion exists from Person to string by default. 没有我们的隐式运算符,这将(显然)在编译时失败,因为默认情况下不存在从Personstring的转换。

Explicit operators are similar, but work the other way. 显式运算符相似,但工作方式相反。 This occurs if we wanted to cast a string to a person . 如果我们想将字符串转换为一个人,则会发生这种情况。 So we could add the following explicit operator: 因此,我们可以添加以下显式运算符:

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

And now we can do this: 现在我们可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM