首页 文章

沮丧和向上倾斜

提问于
浏览
71

我是C#(和OOP)的新手 . 当我有一些如下代码:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

Question 1 :如果我有其他代码执行此操作:

Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

这里 Employee 是一个 Manager ,但当我把它像这样投射到一个 Employee 时,这意味着我正在向上倾斜吗?

Question 2

当我有几个 Employee 类对象时,有些但不是全部都是 Manager ,我怎么能在可能的情况下将它们转发?

5 回答

  • 5
    • 这是对的 . 当你这样做时,你将它转换为 employee 对象,这意味着你无法访问任何经理特定的 .

    • 向下转换是您获取基类然后尝试将其转换为更具体的类的地方 . 这可以通过使用is和这样的显式转换来完成:

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

    或者像这样的 as 运算符:

    Manager m = (employee as Manager);
    if (m != null)
    {
        //do something with it
    }
    

    如果有什么不清楚我会很乐意纠正它!

  • 5

    Upcasting (使用 (Employee)someInstance )通常很容易,因为编译器可以在编译时告诉您是否从另一个派生类型 .

    然而,通常必须在运行时完成 Downcasting ,因为编译器可能并不总是知道所讨论的实例是否是给定的类型 . C#为此提供了两个运算符 - is ,它告诉您downcast是否有效,并返回true / false . 并且 as 会尝试执行转换并在可能的情况下返回正确的类型,否则返回null .

    要测试员工是否是经理:

    Employee m = new Manager();
    Employee e = new Employee();
    
    if(m is Manager) Console.WriteLine("m is a manager");
    if(e is Manager) Console.WriteLine("e is a manager");
    

    你也可以用这个

    Employee someEmployee = e  as Manager;
        if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");
    
    Employee someEmployee = m  as Manager;
        if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");
    
  • 43

    如果您需要检查每个Employee对象是否是Manager对象,请使用OfType方法:

    List<Employee> employees = new List<Employee>();
    
    //Code to add some Employee or Manager objects..
    
    var onlyManagers = employees.OfType<Manager>();
    
    foreach (Manager m in onlyManagers) {
      // Do Manager specific thing..
    }
    
  • -1
    • Upcasting 是一个从子类引用创建基类引用的操作 . (子类 - >超类)(即经理 - >员工)

    • Downcasting 是一个从基类引用创建子类引用的操作 . (超类 - >子类)(即员工 - >经理)

    在你的情况下

    Employee emp = (Employee)mgr; //mgr is Manager
    

    你正在做一个向上倾斜 .

    与需要显式转换的向下转换相比,转发总是成功,因为它可能在运行时失败 . ( InvalidCastException ) .

    C#提供了两个运算符来避免抛出此异常:

    从...开始:

    Employee e = new Employee();
    

    第一:

    Manager m = e as Manager; // if downcast fails m is null; no exception thrown
    

    第二:

    if (e is Manager){...} // the predicate is false if the downcast is not possible
    

    Warning :当您进行上传时,您只能访问超类的方法,属性等...

  • 70

    向上倾斜和向下倾斜:

    向上转换:从派生类转换为基类向下转换:从基类转换为派生类

    让我们理解同样的例子:

    考虑两个类Shape作为我的父类,Circle作为Derived类,定义如下:

    class Shape
    {
        public int Width { get; set; }
        public int Height { get; set; }
    }
    
    class Circle : Shape
    {
        public int Radius { get; set; }
        public bool FillColor { get; set; }
    }
    

    Upcasting:

    Shape s = new Shape();

    圆圈c = s;

    c和s都引用相同的内存位置,但它们都有不同的视图,即使用“c”引用,您也可以访问基类和派生类的所有属性,但使用“s”引用可以访问属性唯一的父类 .

    转发的一个实际例子是Stream类,它是.net框架的所有类型的流读取器的基类:

    StreamReader reader = new StreamReader(new FileStreamReader());

    在这里,FileStreamReader()被提升为streadm reder .

    Downcasting:

    Shape s = new Circle();在这里,如上所述,s的视图是唯一的父母,为了使父母和孩子同时我们需要向下传播它

    var c =(Circle)s;

    Downcasting的实际例子是WPF的按钮类 .

相关问题