沮丧和向上倾斜

我是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)

3 years ago

  • 这是对的 . 当你这样做时,你将它转换为 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
}

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

3 years ago

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");

3 years ago

如果您需要检查每个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..
}

3 years ago

  • 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 :当您进行上传时,您只能访问超类的方法,属性等...

3 years ago

向上倾斜和向下倾斜:

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

让我们理解同样的例子:

考虑两个类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的按钮类 .