2

我知道在扩大转换中,目标数据类型可以保存源数据类型提供的任何值。我可以在转换值类型时理解这一点,但不能在引用类型之间。我的问题来自以下场景:

public class Person
{
    public string Name { get; set; }
}

public class Employee : Person
{
    public string SurName { get; set; }
}
static void Main(string[] args)
{
    Employee emp = new Employee { Name = "Elvin", SurName = "Mammadov" };
    Person prs = emp;
}

如图所示,Person类是Empoyee的祖先类。在之前的代码中,我创建了Emplyee类的引用,然后将Employee对象转换为 Person。此时,我丢失了SurName数据字段和值。

我想知道:

  1. 可以容纳任何价值表达的国家吗?

  2. 为什么将引用类型转换为直接或间接祖先类或接口是扩大转换?

谢谢您的回复

4

1 回答 1

4

这将被称为“扩大转换”,因为您在引用类型方面变得不那么具体,您正在扩大潜在类型的集合。当您有Employee引用时,您知道您可以使用特定于该类的任何功能,当您Person引用同一对象时,您只知道您可以使用Person该类中包含的功能。如果你想在你的引用中使用Employee特定的功能,你prs首先必须将你的引用转换回一个Employee引用,如果prs它实际上不是类型Employee(也许它Customer也是继承自的类型Person),那么你会得到一个InvalidCastException.

当您处理参考时,该SurName属性不会消失。Person您只是无法访问它,因为它不包含在Person类中。基本上,如果您有基类类型的引用,您将只能访问包含在基类中的属性/方法。它实际上是一个并不重要Employee,你有一个Person引用,所以对象会被相应地处理。

转换在您的示例中没有用。当您尝试以通用方式处理许多子类时,转换很有用。例如,我可能有一Person堂课。除此之外,我还有从它继承的EmployeeCustomer和类。Consultant现在假设我有一个Store对象,我想做一些事情,比如获取Person当前在商店中的每个人的名字。解决此问题的最简单方法是List<Person>与商店中的所有人一起进行。因为Employee, Customer, 和Consultant所有继承自我Person可以做

peopleInMyStore.Add(MyEmployee);
peopleInMyStore.Add(MyCustomer);
peopleInMyStore.Add(MyConsultant);

然后稍后我可以做类似的事情;

foreach (Person p in peopleInMyStore)
{
     Console.WriteLine(p.Name);
}

这个概念被称为“多态性”,可以在这里阅读http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

我的示例是人为的,但这是您使用继承的主要原因之一。给你一个真实的例子,我有一些测试代码,其中我有一个名为的类ApiTestSuite,然后我有大约十几个类都继承自它的形式SpecificApiTestSuite。该项目构建为命令行可执行文件,您使用 api 参数 (api=specificApiName) 调用它,然后我可以执行以下操作;

 ApiTestSuite tests;
 if (args[0] == "api1")
     tests = new Api1TestSuite();
 else
     tests = new Api2TestSuite();
 tests.RunTests();
于 2013-08-23T22:22:50.360 回答