问题描述
我知道在扩展转换中,目标数据类型可以保存源数据类型提供的任何值.转换值类型时,我可以理解这一点,但不能在引用类型之间.我的问题来自以下场景:
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.
我想知道:
-
可以保存任何值 表达式是否正确?
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
类.除此之外,我还有从其继承的Employee
,Customer
和Consultant
类.现在,假设我有一个Store
对象,我想做一些事情,例如获取商店中当前每个Person
的名字.解决此问题的最简单方法是在商店中与所有人一起使用List<Person>
.因为Employee
,Customer
和Consultant
都继承自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();
这篇关于扩大参考类型之间的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!