【问题标题】:why is it when I try to create a child class from a parent class(Downcasting), I get a null object为什么当我尝试从父类(向下转换)创建子类时,我得到一个空对象
【发布时间】:2020-10-01 11:18:10
【问题描述】:
namespace Test
{  
    public class Basic
    {

        public virtual void WriteIt()
        {
            Console.WriteLine("Hi");
        }
    }

    public class Not_So_Basic : Basic
    {
        public override void WriteIt()
        {
            Console.WriteLine("Hi2");
        }
    }
    class Program
    {

        static void Main(string[] args)
        {

            Not_So_Basic obj = new Basic() as Not_So_Basic;
            if(obj==null)
                Console.WriteLine("Error");
            else
            obj.WriteIt();
        }



    }
}

所以基本上我创建了这两个类,Basic 和 Not_So_Basic,它们是 Basic 类的子类。

当我尝试通过向下转换使用其父类的对象来创建 Not_So_Basic 类的对象时,我总是得到一个空对象。

我理解这样做,我只是将我的子类对象引用到父类对象,我得到了“子类视图”,对吧?我并没有真正在基于父类的子类的堆中创建一个单独的空间。

我是编程新手,所以请温柔一点,不要烤我。我确信有一条规则我正在打破。 顺便说一句,我正在努力学习编程,我不是在做一个项目,只是想把我的脑袋绕在一个我正在打破的规则上。

代码是用c#编写的。

【问题讨论】:

  • 因为它不是真正的Not_So-Basic 对象。 as 运算符就是不能那样工作的。从逻辑的角度来看,不能将基类型视为派生类型是有道理的。

标签: c# .net class oop


【解决方案1】:

as operator 尝试强制转换,但如果不能,则为您提供 null 对象。所以这意味着演员失败了。

您正在将 Basic 对象转换为 Not_So_Basic。你不能这样做,因为Basic 不继承自Not_So_Basic

为了说明,所有狐狸都是动物,但并非所有动物都是狐狸,因此您不能将 Animal 转换为 Fox

也就是说,如果您有一个实际的 Not_So_Basic 对象,它只是表示为 Basic 对象,那么您可以将其转换为 Not_So_Basic。例如:

Basic basic = new Not_So_Basic();

Not_So_Basic not_so_basic = (Not_So_Basic) basic; //this works

【讨论】:

  • 所以基本上每次我想使用从基于“父”的类对象向下转换到它的一个子对象时,我必须确保基于“父”的类对象指向相同类型的我想将其转换为“child”类的子类的“child”类的 or and ?
  • 正确。这就是为什么它是运行时异常而不是编译器错误的原因——因为有时它是有效的,有时它不是。但这就是我们有asis 的原因,这样您就可以毫无例外地处理糟糕的演员阵容。
  • 好的,就是这样!太感谢了!现在一切都清楚了!祝你有美好的一天^__^
【解决方案2】:

向下转换是您采用基类,然后尝试将其转换为更具体的类。这可以通过使用as 来完成,如下所示:

Not_So_Basic notSoBasic = basic as Not_So_Basic;

只有当basic 引用Not_So_Basic 的实例时,转换才会成功

//successful cast
Basic basic = new Not_So_Basic();
Not_So_Basic notSoBasic = basic as Not_So_Basic;

OR basic 指的是Not_So_Basic child 的一个实例。

public class Not_So_Basic_Child : Not_So_Basic
    {
        public override void WriteIt()
        {
            Console.WriteLine("Hi from child");
        }
    }

//another successful cast
Basic basic = new Not_So_Basic_Child();
Not_So_Basic notSoBasic = basic as Not_So_Basic;

如果您尝试将基类的实例强制转换为子类的实例,as 运算符将返回 null

//unsuccessful cast
Basic basic = new Basic();
Not_So_Basic notSoBasic = basic as Not_So_Basic; //is null

【讨论】:

    【解决方案3】:

    参照父类创建子类对象,结果将始终为空。我们不能这样创建子类对象。

    //unsuccessful cast
    Parent parent = new Parent();
    Child child = parent as Child; //is null
    

    正确方法:

    Parent parent= new Child();
    Child  child = (Child) parent; //this works
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      • 2018-11-24
      • 2015-03-17
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      相关资源
      最近更新 更多