简体   繁体   English

在 C# 中将类型转换为另一种类型

[英]casting a type to another type in C#

I'm a beginner in OOP, just have a question on casting, let's say we have:我是 OOP 的初学者,只是有一个关于铸造的问题,假设我们有:

interface Animal
{
   string speak();
}

class Dog : Animal
{
   public string speak()
   {
       return "wan-wan";
   }
}

class Cat : Animal
{
   public string speak()
   {
     return "miao";
   }

   public void catchMouseS()
   {
      ...
   }
}

class Program
{
   static void Main(string[] args)
   {
     Animal generic= new Dog();
     Cat cutie = (Cat)generic;   
    }
}

so you can see that I can type a dog to a cat, the compiler is OK with that, shouldn't the compiler be smart enough to throw an error, because it will encounter error on run time for sure when the 'cutie' calls the catchMouses method since cutie is actually a dog which doesn't have catchMouses method?所以你可以看到我可以给一只猫输入一条狗,编译器可以接受,编译器不应该足够聪明来抛出错误,因为它肯定会在运行时遇到错误,当“cutie”调用时catchMouses 方法,因为 cutie 实际上是一只没有 catchMouses 方法的狗?

This is just the way polymorphism and interfaces work in .Net.这就是 .Net 中多态性和接口的工作方式。

The compiler can statically analyse the Type of the Reference , but it doesn't dig into the run-time Type of the object in memory.编译器可以静态分析引用类型,但它不会深入研究内存中对象的运行时类型 It knows enough to know those 2 types implement the same contract and can make an Explicit Conversion , and it's good with that for good reasons.它知道这两种类型实现了相同的契约并且可以进行显式转换,这是有充分理由的。

Now, to you and me it's obvious Dog is not a Cat , we can see it in a handful of code, but the compiler doesn't try and figure out that type of problem at compile time.现在,对你和我来说很明显Dog不是Cat ,我们可以在少数代码中看到它,但是编译器不会在编译时尝试找出那种类型的问题。 You could imagine if you had a million lines of code it would have to check billions (if not trillions) of path-ways to work-out if what you are doing is correct... All it knows at compile time is the Type at casting is valid (not what you try to do with it), and a conversion is possible.你可以想象,如果你有 100 万行代码,它必须检查数十亿(如果不是数万亿)的路径来解决你所做的是否正确......它在编译时只知道类型是强制转换是有效的(不是您尝试用它做的),并且可以进行转换。

So, to save time on what is really an enormous problem with lots of degrees of freedom, (the compiler) does a basic Static Check to see if there is a possible conversion, and allows you to make a mess of it, however it still does the run-time check.因此,为了节省时间解决真正具有大量自由度的巨大问题,(编译器)进行基本的静态检查以查看是否存在可能的转换,并允许您将其弄得一团糟,但是它仍然进行运行时检查。

Here is another way to hoodwink the compiler这是另一种欺骗编译器的方法

class Dog
{
}

class Cat
{
}

public static void Main()
{
    Dog d = new Dog();
    var a = (object)d;
    Cat cutie = (Cat)a;
}

Both are reference types , both can be converted to object , and both conversion are seemingly possible, so it thinks you know what you are doing at compile time, obviously though the run-time checks fail.两者都是引用类型,都可以转换为object ,并且这两种转换似乎都是可能的,因此它认为您在编译时知道自己在做什么,显然虽然运行时检查失败。

The case you described is called downcasting and is considered a bad code for the exact reason you have mentioned.您描述的情况称为向下转换,并且由于您提到的确切原因而被认为是错误的代码。 It is allowed at compile time, and crashes (or misbehaves) in runtime (or not).它在编译时被允许,并在运行时(或不会)崩溃(或行为不端)。

You could also catch InvalidCastException and do something with it.您还可以捕获InvalidCastException并对其进行处理。

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

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