C# 何时以及为什么要向上投射对象?

C# 何时以及为什么要向上投射对象?,c#,.net,oop,class,casting,C#,.net,Oop,Class,Casting,这被认为是向上投射正确吗 Derived d = new Derived(); Base b = d; // Always OK. 为什么会有人上抛?什么时候是因为我们必须将对象转换为基类,这样它就没有派生类的功能了吗 这段代码在内存中看起来如何?派生类实例化并为该对象创建内存。然后创建一个基类对象,该对象现在引用d。向上转换是正常的,因为每个派生的都是基类 当您编写从类a继承的类B时,B是a的子类。这意味着您可以在任何可以使用类型a的对象的地方使用类型B的对象 您应该了解它的功能和功能。当您

这被认为是向上投射正确吗

Derived d = new Derived();
Base b = d; // Always OK.
为什么会有人上抛?什么时候是因为我们必须将对象转换为基类,这样它就没有派生类的功能了吗


这段代码在内存中看起来如何?派生类实例化并为该对象创建内存。然后创建一个基类对象,该对象现在引用
d

向上转换是正常的,因为每个
派生的
都是
基类

当您编写从类a继承的类B时,B是a的子类。这意味着您可以在任何可以使用类型a的对象的地方使用类型B的对象

您应该了解它的功能和功能。

当您想使用时,您可以使用upcast,例如,您有一个方法接受
,但您喜欢用
派生的
调用它:

public void DoAction(Base base)
{
 // do stuff
}

DoAction(drivedItem);

DoAction(baseItem);
以上两种说法都是正确的


但在多态性中,您不能进行向下转换,您可以使用例如方法重载来克服您的问题。

我不确定您是否经常编写类似于示例的代码,但这种类型转换的一个应用程序是方法调用:

void Test()
{
   Derived d = new Derived();
   this.DoSomething(d);
}

void DoSomething(Base b)
{
   // something
}
在这种情况下,
d
并没有“变成”一个
Base
对象,它只是被当作一个对象对待。我不确定,但我想与
d
对象相关的实际内存根本不会改变

这是因为我们必须将对象转换为基类,这样它就没有派生类的功能了吗

因为无论您的对象是
Derived1
还是
Derived2
都有一些代码可以工作,并且只基于支持
Base
功能的假设编写。这称为抽象,将导致代码重用。您不必分别为
Derived1
Derived2
重写该函数。您可以抽象掉特定于
Derived1
Derived2
的详细信息

顺便说一句,很多时候,您并没有显式地执行强制转换。当您将实例传递给函数时,只需利用这一事实。例如,当您将
字符串
添加到
数组列表
时,您会将其隐式转换为其基类型
对象
,因为
添加
的签名是:

void Add(object o);

关于第二个问题(它们在内存中的外观),它们在堆栈中的外观相同。在堆栈上,它们都是指向堆的简单指针。

原因一:如果我在2008年编写的代码了解
类,并使用它做一些只涉及该类功能的事情,upcasting允许您在2011年创建
派生的
类,并在不做任何更改的情况下将实例传递给my code

可以说,如果我首先使用泛型编写代码,也可以做到这一点(而且可能更强大)


原因二:如果需要在单个容器中存储不同类的多个实例,则需要将这些实例向上转换为共享基类。例如,考虑一个“当前加载”数据源的列表,这些数据源可能是本地文件、URL、内存数据甚至是套接字——所有这些都是共享公共数据源类的特定类。

< P>我认为您可能对上报的内容有点迷惑。向上转换不会禁用派生对象的功能,也不会创建新的基础对象。相反,它只是对您向上投射的对象进行更有限的查看。通过基类引用,您只能访问在基类中声明的那些方法,但是如果这些方法中的任何一个在派生类中被重写,那么通过基类引用调用它们仍将调用派生版本


当你想这样做的时候,看到人们无缘无故地向上看是很少见的。毕竟,这限制了您可以对对象执行的操作。然而,正如其他海报所指出的,在将对象传递到函数或从函数返回对象时,隐式向上转换是很常见的。在这些情况下,向上转换允许函数作者要么接受完成任务所需的最弱需求集的参数,要么从显示某些行为集的函数返回对象,而不必显示对象的完整类型。

您希望何时向上转换代码?为什么?是的,派生的是Base,但现在是什么?@RoR这意味着您可以编写与Base一起工作的共享代码,并且从Base派生的每个类都可以使用此共享代码。它们很有用,因为有时您不关心派生的对象是什么,您只需要在
Base
中使用泛型方法,例如对于DB对象,在需要保存的地方,这对于所有DB对象都是一样的,而不管非OO多态性中的其他细节如何,您可以使用模式匹配进行向下转换;-)