【问题标题】:Invalid Cast Exception but build works fine无效的转换异常,但构建工作正常
【发布时间】:2021-09-26 18:37:03
【问题描述】:
public class A
    {
        public void M1()
        {
            Console.Write("Print M1 of Class A");
        }
    }
public class B:A
{
    public void M2()
    {
        Console.Write("Print M2 of Class B");
    }
}

public class C : B
{
    public void M3()
    {
        Console.Write("Print M3 of Class C");

    }
}

在 main 方法中,我们创建如下对象:-

   A objA = new B();
    B objB = new C();
    A a = new A();
    C objC = (C)a;  /* this line throws runtime error System.InvalidCastException: 'Unable to cast object of type 'A' to type 'C'.'  but build works fine */

        objA.M1();
        objB.M1();
        objB.M2();
        objC.M1();
        objC.M2();
        objC.M3();

我不能先将 C 直接转换为 A。因此尝试创建对象 A 然后显式转换它。智能感知将其视为有效代码并且构建也很好,但在控制台应用程序执行期间,它会抛出错误“无法将'A'类型的对象转换为'C'类型。”

【问题讨论】:

  • 是的,a 属于 (base) 类型 A 并且不能转换为 C,因为 C派生的 i> 来自A。反过来也是可能的:derivedC 的对象 c 可以转换为 baseA: C c = new C(); A objA = (A) c;
  • 同一继承树中引用类型之间的转换是“这个变量说它是x,但我知道它真的是y,相信我编译器我比你更了解”。它不会将x转换y,程序员在断言它始终是y(或者更进一步的派生)

标签: c# exception casting


【解决方案1】:

这是真的;您可以随时将 C 转换为 A,但唯一可以反过来执行的方法是,如果您将 C 存储在类型为 A 的变量中。编译器允许您这样做,因为 C 来自 A ,因此 A 类型的变量能够保存 C 类型的实例。因此,您可以合法地将 C 存储在 A 中,并且您正在强制将其恢复为 C:

A reallyC = new C();
C gotBack = (C)reallyC;

编译器不会太看重你之前所做的事情;它不会看到这样的代码:

A reallyA = new A();
C willFail = (C)reallyA;

然后说“嘿;你已经在 realA 中存储了一个 A,它不能转换为 C”。它只是看到你试图将真的 A 转换为 C 并认为“它可能是 C,因为 C 是 B 是 A,所以它们是相关的。我相信开发人员知道他们在做什么,我会允许的”

【讨论】:

  • 它编译并不意味着它是正确的。这是一个明显的例子。在 A 中使用 C 是很常见的——查看事件处理程序。第一个参数是发送者——它是对象类型。显然,您几乎总是必须强制转换才能使用它。
  • 好点:每个人写的代码总是编译得很好,但不对。 “做,做,做对”——“做对”部分被称为“修复错误”。哦,然后让它快点。 ?
【解决方案2】:

好吧,a 属于 (base) 类型 A 并且不能转换为 C,因为 C 是从 @987654325派生 @。反过来也是可能的:派生C的对象c可以转换为baseA

 C c = new C(); 
 A objA = (A) c;

我们通常可以尝试is的帮助下进行投射:

if (a is C objC) {
  // a can be cast to C, objC now holds the result of the cast  
  objC.M3();
}
else {
  // the cast is impossible
}

【讨论】:

    猜你喜欢
    • 2020-02-13
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多