将基类转换为派生类

don*_*y76 1 c#

基本上有2个班级。

class Motor {
   int a;
   int b;
   int c;
}

class Title : Motor {
    int d;
    int e;
}
Run Code Online (Sandbox Code Playgroud)

现在,函数将与Motor类的实例一起传递。

bool AssignNums(Motor m)
{
   Title t = (Title)m;   //throws exception
   //Do other things with "t"
}
Run Code Online (Sandbox Code Playgroud)

叫做,

void AddNums()
{
   Motor m = new Motor();
   m.a = 23;
   m.b = 78;
   m.c = 109;
   AssignNums(m);
}
Run Code Online (Sandbox Code Playgroud)

上面的强制转换行无效。它抛出一个空指针异常。

我试过了:

bool AssignNums(Motor m)
{
   Title t = new Title();
    t  = (Title)m; // Doesn't work.
   //Do other things with "t"
}
Run Code Online (Sandbox Code Playgroud)

上面的方法也不起作用。

来自C ++背景,很难理解C#在C#中是如何工作的。

在C ++中,以下代码将起作用。

bool AssignNums(Motor* m)
{
   Title* t = (Title*)m; //Will work
   //Do other things with "t"
}
Run Code Online (Sandbox Code Playgroud)

如何在C#中完成?无需大量代码即可实现“反射”或类似功能……

Eri*_* J. 6

在C#中,您不能将对象转换为更特定的子类。想象一下如果可能的话会发生什么:

class Foo : Motor
{
    int z;
}

Foo m = new Foo();

bool AssignNums(Motor m)
{
   Title t = (Title)m;   // Pretend it doens't throw an exception
   //Do other things with "t"
   t.d = 42; // Oopps! The actual object is Foo, not Title, so there is no field called d
             // InvalidCastException is thrown at the line that attempts the cast
}
Run Code Online (Sandbox Code Playgroud)

如果实际类型与所需类型兼容,则可以在运行时对其进行转换:

bool AssignNums(Motor m)
{
   Title t = m as Title;   
   if (t != null)
   {
       // Do stuff with t
   }
}
Run Code Online (Sandbox Code Playgroud)

从C#7开始,您可以使用较短的形式

bool AssignNums(Motor m)
{
   if (m is Title t)
   {
       // Do stuf with t
   }
}
Run Code Online (Sandbox Code Playgroud)

如果处理多个子类,则还可以使用switch..when

switch (m)
{
    case Title t when m is Title:
        // Do something with t
        break;
    case Foo f when m is Foo:
        // Do something with f
        break;
}
Run Code Online (Sandbox Code Playgroud)

但是请注意,如果您基于运行时存在的子类进行分支,则表明您可能存在设计问题。