题
我是新来的 C# (和 面向对象编程)。当我有如下代码时:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
问题1:如果我有其他代码可以执行此操作:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
这里 Employee
是一个 Manager
, ,但是当我把它像这样投射到 Employee
这意味着我正在升级它?
问题2:
当我有几个 Employee
类对象,其中一些但不是全部是 Manager
的,我怎样才能尽可能地让他们失望?
解决方案
那是对的。当你这样做时,你正在将它投射到一个
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
}
如果有任何不清楚的地方,我很乐意纠正!
其他提示
<强>向上转型强>(使用(Employee)someInstance
)通常是很容易,因为编译器可以在编译时告诉你,如果一个类型是从另一个导出的。
<强>向下转换强>但是具有在运行时进行通常的编译器可能并不总是知道所讨论的实例是否是给定的类型。 C#提供了两个操作人员这一点 - 是告诉你,如果垂头丧气的作品,并返回真/假。和作为强>它试图做铸造和如果可能的话返回正确的类型,或者为空,如果不
要测试是否雇员是经理:
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");
- 向上转型 是从子类引用创建基类引用的操作。(子类 -> 超类)(即经理 -> 员工)
- 贬低 是从基类引用创建子类引用的操作。(超类 -> 子类)(即员工 -> 经理)
在你的情况下
Employee emp = (Employee)mgr; //mgr is Manager
你正在做一个向上转型。
向上转型总是成功,与需要显式转型的向下转型不同,因为它可能在运行时失败。(无效转换异常).
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
警告:当你进行向上转换时,你只能访问超类的方法、属性等......
在的情况下,需要检查每个Employee对象是否是管理对象的,使用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: 是的,它叫做上溯造型,但你做的方式是不是现代的方式。上溯造型可以执行隐含你不需要任何转换。所以只是写的雇员EMP =经理; 强> 是足够的向上转型。
答2: 如果创建Manager类的对象,我们可以说,经理是雇员。因为<强>类管理器:雇员强>描绘的是-A Employee类和管理器类之间的关系即可。因此,我们可以说,每一个经理是雇员。
但是,如果我们创建Employee类的对象,我们不能说这是员工,因为经理的 Employee类是一个不继承任何其他类的类。所以你不能直接向下转换该Employee类对象管理器类对象。
所以答案是,如果你想从Employee类对象向下转型到管理类对象,首先你必须有Manager类的对象第一,那么你可以上溯造型,然后你可以垂头丧气了。
向上转型和向下转换:
向上转型:从铸造派生类的基类 向下转换:从基类投放到派生类
让我们了解相同的示例:
考虑两个类形状为My父类和圆作为派生类,定义如下:
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; }
}
<强>向上转型:强>
形状s =新式样();
圆C = S;
C和s的引用到相同的存储器位置,但两者有不同的观点即,使用“C”的参考可以访问的基类的所有属性和派生类,以及,但使用“S”你参考可以访问的唯一父类的属性。
向上转型的一个实际的例子是流类,这是所有类型的.NET框架的流读取器的基类:
StreamReader的读者=新的StreamReader(新FileStreamReader());
这里,FileStreamReader()被upcasted到streadm REDER。
<强>向下转换:强>
形状s =新圈(); 这里,如上所述,图S的是唯一的父,为了使其成为父级和我们需要向下转换它的子
变种C =(圆)S;
向下转换的实际的例子是按钮类WPF的。