为什么C#编译器没有捕获到InvalidCastException [英] Why doesn't the C# compiler catch an InvalidCastException

查看:40
本文介绍了为什么C#编译器没有捕获到InvalidCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
编译时和运行时转换c#

据我了解,以下代码将始终进行编译,并且还会在运行时因抛出 InvalidCastException 始终失败.

As I understand it, the following code will always compile, and will additionally always fail at run-time by throwing an InvalidCastException.

示例:


public class Post { }
public class Question : Post { }
public class Answer : Post 
{
    public void Fail()
    {
        Post p = new Post();
        Question q = (Question)p; // This will throw an InvalidCastException
    }
}

我的问题是...

  1. 如果我的假设不成立,那么有人可以提供一个示例来说明他们的状况如何吗?
  2. 如果我的假设是正确的,那么为什么编译器不针对此错误发出警告?

推荐答案

允许进行此转换的原因有两个.

There are a couple of reasons why this conversion is allowed.

首先,正如人们在其他答案中所说的那样,强制转换运算符的意思是我比你了解更多;我保证你这种转换将成功,如果我错了,抛出异常并使过程崩溃".如果您对编译器撒谎,那么糟糕的事情将会发生.您实际上不是 做出保证,因此程序 崩溃了.

First, as people have said in other answers, the cast operator means "I know more than you do; I guarantee you that this conversion will succeed and if I am wrong, throw an exception and crash the process". If you are lying to the compiler, bad things are going to happen; you in fact are not making that guarantee, and the program is crashing as a result.

现在,如果编译器可以告诉您您对它撒谎,那么它可以抓住您的谎言.不需要编译器任意巧妙地抓住您的谎言!确定Base类型的表达式为从不变为Derived类型所需的流程分析很复杂;比我们已经实现的用于捕获未分配的局部变量之类的逻辑要复杂得多.与提高编译器以明显的谎言吸引您的能力相比,我们有更好的方法来花费时间和精力.

Now, if the compiler can tell that you are lying to it, then it can catch you in the lie. The compiler is not required to be arbitrarily clever in catching you in your lies to it! The flow analysis needed to determine that an expression of type Base is never going to be of type Derived is complex; considerably more complex than the logic we already implement to catch things like unassigned local variables. We have better ways to spend our time and effort than in improving the compiler's ability to catch you out in obvious lies.

因此,编译器通常仅考虑表达式的类型,而不考虑可能的值.仅从类型分析中就不可能知道转换是否成功.它可能成功,因此被允许.唯一不允许使用的强制类型转换是编译器从类型分析中得知总是失败的强制类型转换.

The compiler therefore typically reasons only about types of expressions, not about possible values. Solely from the type analysis it is impossible to know whether or not the conversion will succeed. It might succeed, and so it is allowed. The only casts that are disallowed are the ones that the compiler knows will always fail from the type analysis.

第二,说(Derived)(new Base())可能是 ,其中Derived是实现Base类型并具有 not 在运行时失败.(Base)(new Base())也有可能在运行时因强制转换异常而失败!真实的事实!这些是非常罕见的情况,但是 是可能的.

Second, it is possible to say (Derived)(new Base()) where Derived is a type that implements type Base and have it not fail at runtime. It is also possible for (Base)(new Base()) to fail with an invalid cast exception at runtime! True facts! These are extraordinarily rare situations but they are possible.

有关更多详细信息,请参阅我关于该主题的文章:

For more details, see my articles on the subject:

http://blogs.msdn.com/b/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx

http://blogs.msdn.com/b/ericlippert/archive/2007/04/18/chained-user-defined-explicit-conversions-in-c-part-two.aspx

http://blogs.msdn.com/b/ericlippert/archive/2007/04/20/chained-user-defined-explicit-conversions-in-c-part-three.aspx

这篇关于为什么C#编译器没有捕获到InvalidCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆