【问题标题】:Not throwing error in compile time when casting base to derived class [duplicate]将基转换为派生类时不会在编译时引发错误[重复]
【发布时间】:2015-04-26 04:00:38
【问题描述】:

你有这些类如下所示:

public class A
{
}

public class B : A
{
}

您将基类转换为派生类的类型

A w = (B) new A();    
B x = (B) new A();

这在运行时不起作用,因为您不能真正将基类转换为派生类。

但是why is there no compile time error?为什么 Visual Studio 允许我在抛出错误之前达到运行时?

【问题讨论】:

  • 这可能会有所帮助:ericlippert.com/2012/07/10/696
  • C#编译器允许explicit从派生类转换为基类,但你必须确保没有运行时错误
  • 这实际上是错误的,无论您编写显式或隐式转换,在运行时您都会收到异常,因为不允许转换为派生类。

标签: c# oop casting


【解决方案1】:

有两种类型的演员表

  • 当类没有共同的基础并因此演员没有机会成功时,这显然是不允许的。 IE。 “字符串”到“整数”。这样的转换被编译器捕获并导致错误。
  • 有机会成功的施法 - 基础到派生有合理的成功机会。编译器允许此类转换。

我相信即使强制转换失败,在编译时也允许(B)new A() 的原因是因为(B)someObjectOfTypeA 可以成功,而new A() 绝对是这样的“A 类对象”之一。编译时检测可能需要额外的基础设施并且没有发现有益(因为这种转换在运行时立即失败,因此即使是最基本的代码测试也不太可能错过)。

【讨论】:

  • ahhh .. 所以你的意思是微软可能有办法在编译时引发错误,但发现这是一个小问题,因为他们确定它会在运行时失败?
  • “基础到派生有合理的成功机会” - 你能举个例子吗?
  • “可能有办法在编译时引发错误” - 这是我的猜测。我对规范不够熟悉,无法知道它是实际要求还是恰好是这样。
  • @RojBeraña (B)(A)(new B()) - 有 100% 的机会成功将具有编译类型 A - (A)new B() 的变量转换为派生类 B。还有很多转换应该成功但编译器可以'当你处理泛型时你想不通,你会看到像(T)(object)argument 这样的奇怪代码(Eric Lippert 的article 中涵盖了一些有趣的案例,早先在 cmets 中链接)
  • 可能成功的现实世界场景:Animal a = new Dog();狗 d = (狗) a;
【解决方案2】:

在 c# 中,用户定义的类在运行时进行强制转换,这就是编译器不会抛出错误的原因。您可以查看this 了解更多信息。从一种基本类型(字符串)到另一种基本类型(int)的转换称为编译时间,因为编译器知道字符串不能类型转换为 int!但是在用户定义的类中,有机会! :)

【讨论】:

  • 但是为什么在编译时已经抛出错误,代码:int d = 23; var f = (bool) d;
  • 呵呵.. 错过了这一点。 int 和 bool 是已知类型,在运行时它们不可能正确转换,因此您会看到错误。相应地编辑了答案:)对不起,我的错误。
猜你喜欢
  • 2012-09-15
  • 2018-09-30
  • 1970-01-01
  • 2020-08-21
  • 2022-10-14
  • 2017-01-08
  • 2013-11-17
相关资源
最近更新 更多