我是 C#(以及 OOP )的新手。当我有一些如下代码时:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
问题1 :如果我有其他代码执行此操作:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
此处Employee
是Manager
,但当我将其转换为Employee
时,这意味着我正在向上转播它?
问题2 :
当我有多个Employee
类对象时,有些但不是全部都是Manager
,我怎么能在可能的情况下将它们转发?
答案 0 :(得分:79)
这是对的。执行此操作时,您将其转换为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
}
如果有什么不清楚我会很乐意纠正它!
答案 1 :(得分:47)
向上转换(使用(Employee)someInstance
)通常很简单,因为编译器可以在编译时告诉您类型是否来自另一个类型。
向下转换通常必须在运行时完成,因为编译器可能并不总是知道所讨论的实例是否是给定的类型。 C#为此提供了两个运算符 - 是,它告诉您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");
答案 2 :(得分:9)
在你的情况下
Employee emp = (Employee)mgr; //mgr is Manager
你正在进行预告。
upcast总是成功,不像需要显式转换的downcast,因为它可能在运行时失败。( 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
警告:当您进行转播时,您只能访问超类的方法,属性等......
答案 3 :(得分:6)
如果您需要检查每个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..
}
答案 4 :(得分:0)
答案1: 是的,它称为“转换”,但您的操作方式不是现代方式。可以隐式执行向上转换,无需任何转换。因此,只需编写 Employee emp = mgr; 足以进行投射。
答案2: 如果创建Manager类的对象,我们可以说经理是雇员。因为 Class Manager:Employee 描述了Employee Class和Manager Class之间的 Is-A关系。所以我们可以说每个经理都是雇员。
但是,如果我们创建Employee类的对象,则不能说此雇员是经理,因为 class Employee 是不继承任何其他类的类。因此,您不能直接将Employee Class对象转换为Manager Class对象。
因此,答案是,如果要从Employee Class对象下放到Manager Class对象,首先必须具有Manager Class的对象,然后才能上载,然后再下放。
答案 5 :(得分:-1)
向上转发和向下倾斜:
向上转换:从派生类转换为基类 向下转换:从基类转换为派生类
让我们理解同样的例子:
考虑两个类Shape作为我的父类,Circle作为Derived类,定义如下:
CREATE PROCEDURE dbo.procedure (@var int)
AS
BEGIN
SELECT * FROM dbo.function(@var)
END
<强>向上转型:强>
Shape s = new Shape();
圈c = s;
c和s都引用相同的内存位置,但它们都有不同的视图,即使用“c”引用,你也可以访问基类和派生类的所有属性,但使用“s”引用你可以访问唯一父类的属性。
上传的一个实际例子是Stream类,它是.net框架的所有类型的流阅读器的基类:
StreamReader reader = new StreamReader(new FileStreamReader());
这里,FileStreamReader()被上传到streadm reder。
<强>向下转换:强>
Shape s = new Circle(); 在这里,如上所述,s的视图是唯一的父母,为了使父母和孩子同时我们需要向下传播它
var c =(Circle)s;
Downcasting的实际示例是WPF的按钮类。