Jer*_*ins 10 .net c# compiler-construction compilation exception
可能重复:
编译时和运行时转换c#
据我所知,以下代码将始终编译,并且还会在运行时始终通过抛出一个失败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
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是......
Eri*_*ert 15
有几个原因可以解释为什么允许这种转换.
首先,正如人们在其他答案中所说的那样,演员操作符意味着"我知道的比你做得更多;我向你保证这个转换会成功,如果我错了,抛出异常并使进程崩溃".如果你对编译器撒谎,那么坏事就会发生; 你其实是没有做这样的保证,程序是崩溃的结果.
现在,如果编译器可以告诉你说谎,那么它可以让你陷入困境.编译器不需要任意聪明地抓住你的谎言!确定Base类型的表达式永远不会是Derived 类型所需的流分析是复杂的; 比我们已经实现的逻辑要复杂得多,比如未分配的局部变量.我们有更好的方法来花费我们的时间和精力,而不是提高编译器在明显谎言中抓住你的能力.
因此,编译器通常只会考虑表达式的类型,而不是可能的值.仅从类型分析中就不可能知道转换是否会成功.它可能会成功,所以它是允许的.唯一不允许的强制转换是编译器知道的类型分析总是失败的.
其次,可以说(Derived)(new Base())Derived是一个实现类型Base的类型,并且它在运行时不会失败.(Base)(new Base())在运行时也可能因无效的强制转换异常而失败!真实的事实!这些是非常罕见的情况,但它们是可能的.
有关详细信息,请参阅有关此主题的文章:
McK*_*Kay 11
Post在某些情况下,A 可以被投射到Question.通过执行强制转换,你告诉编译器,"这将有效,我保证.如果没有,你可以抛出无效的强制转换异常."
例如,这段代码可以正常工作:
Post p = new Question();
Question q = (Question)p;
Run Code Online (Sandbox Code Playgroud)
演员明确表示你比编译器更了解这实际上是什么.您可能需要做一些喜欢as或is关键字?
问题的关键在于,p可能是一个Question问题Post.
考虑以下:
public class Post { }
public class Question : Post { }
public class Banana { }
static class Program {
public static void Main(params string[] args) {
Post p = new Question();
Question q = (Question)p; // p IS a Question in this case
Banana b = (Banana)p; // this does not compile
}
}
Run Code Online (Sandbox Code Playgroud)
当您进行显式转换时,您告诉编译器"我知道您不知道的事情".
你本质上是覆盖了编译器的正常逻辑 - p 可能是Question(因此,编译器将编译),你告诉编译器你知道它(即使它不是,因此运行时异常).
| 归档时间: |
|
| 查看次数: |
1054 次 |
| 最近记录: |