扩大参考类型之间的转换 [英] Widening Conversion between Reference types

查看:89
本文介绍了扩大参考类型之间的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know that in a widening conversion, the destination data type can hold any value provided by the source data type. I can understand this when convert value type, but can't between reference types. My question arises from follows scenario:

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 数据字段和值.

As shown, the Person class is ancestor class of Empoyee. In previouse code, I create reference of Emplyee class, and then convert Employee object into a Person. At this point, I lose SurName data field and value.

我想知道:

  1. 可以保存任何值 表达式是否正确?

  1. Is it countary to can hold any value expression?

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

Why conversion a reference type to a direct or indirect ancestor class or interface is a widening conversion?

感谢回复

推荐答案

这将被称为扩展转换",因为您对引用类型的关注度降低了,正在扩展潜在类型的集合.当您拥有Employee引用时,便知道可以使用该类的任何特定功能,而当您对同一对象具有Person引用时,则仅知道可以使用Person类中包含的功能.如果要对prs引用使用Employee特定功能,则必须首先将引用转换回Employee引用,并且prs实际上不是Employee类型(也许是键入Customer(也继承自Person),那么您将得到一个InvalidCastException.

It would be called a 'widening conversion' because you're becoming less specific with regard to the references type, you're widening the set of potential types. When you have an Employee reference you know that you can use any functionality specific to that class, when you have a Person reference to the same object you only know that you can use functionality contained in the Person class. If you want to use Employee specific functionality with your prs reference you'll first have to cast your reference back to an Employee reference and if prs isn't actually of type Employee (perhaps it's of type Customer which also inherits from Person) then you will get an InvalidCastException.

在处理Person引用时,SurName属性不会消失.您只是无法访问它,因为它不包含在Person类中.基本上,如果您具有基类类型的引用,则只能访问基类中包含的属性/方法.没关系,它实际上是一个Employee,您具有一个Person引用,因此该对象将得到相应处理.

The SurName property does not go away when you're dealing with a Person reference. You just cannot access it because it is not contained within the Person class. Basically, if you have a reference of the base classes type, you will only be able to access properties/methods contained within the base class. It doesn't matter that it is actually an Employee, you have a Person reference, so the object is treated accordingly.

该转换在您的示例中没有用.当您尝试以通用方式使用许多子类时,该转换很有用.例如,我可能有一个Person类.除此之外,我还有从其继承的EmployeeCustomerConsultant类.现在,假设我有一个Store对象,我想做一些事情,例如获取商店中当前每个Person的名字.解决此问题的最简单方法是在商店中与所有人一起使用List<Person>.因为EmployeeCustomerConsultant都继承自Person我可以做

The conversion is not useful in your example. The conversion is useful when you're attempting to work with many child classes in a generic manner. As an example, I may have a Person class. In addition to that I have Employee, Customer, and Consultant classes which inherit from it. Now lets suppose I have a Store object and I want to do something like get the names of every Person who is currently in the store. The simplest way to solve this problem would be to have a List<Person> with all the people in the store. Because Employee, Customer, and Consultant all inherit from Person I could do

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

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

Then later on I can do something like;

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

此概念称为多态",可在此处阅读 http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

This concept is referred to as 'polymorphism' and can be read about here http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

我的示例是人为设计的,但这是使用继承的主要原因之一.为了给您提供一个真实的示例,我有一些测试代码,其中有一个名为ApiTestSuite的类,然后有大约十二个类都以SpecificApiTestSuite的形式从其继承.该项目内置在命令行可执行文件中,您可以使用api参数(api = specificApiName)调用它,然后我可以执行类似的操作;

My example is contrived, but this is one of the main reasons you use inheritance. To give you a real example I have some test code where I have a class called ApiTestSuite then I have about a dozen classes that all inherit from it of the form SpecificApiTestSuite. The project builds into a command line executable, you invoke it with an api parameter (api=specificApiName) then I can do something like;

 ApiTestSuite tests;
 if (args[0] == "api1")
     tests = new Api1TestSuite();
 else
     tests = new Api2TestSuite();
 tests.RunTests();

这篇关于扩大参考类型之间的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆