如果派生类' "参考"超出范围但基类引用仍然存在,派生对象是否会发生变化?

时间:2015-01-22 10:16:41

标签: c# inheritance derived-class

(在C#5.0中)这是一个非常简单的是/否问题,我似乎无法找到明确的答案,这可能意味着我正在寻找错误的地方或使用错误的术语来寻找答案。

如果我创建一个派生类对象,那么我将它转换为基类并且原始引用超出范围,基类类中的引用是否保留整个派生类对象? I.E.我可以稍后将它重新编写为派生类,原始对象始终保持不变吗?

4 个答案:

答案 0 :(得分:4)

C# language specification第6.1.6节(隐式参考转换)中介绍了这一点:

  

隐式或显式的引用转换永远不会更改要转换的对象的引用标识。换句话说,虽然引用转换可能会更改引用的类型,但它永远不会更改所引用对象的类型或值。

(我的重点)


你的问题似乎担心可能会发生类似于Object Slicing的事情 - 但这不是C#中可能发生的事情。

答案 1 :(得分:1)

当然可以。如果转换为其他类型,则仅将视图更改为同一对象。

答案 2 :(得分:1)

它是对同一个对象的引用。具有该引用值的表达式的编译时类型是无关紧要的。重要的是要了解实际上只有一个对象 - 它不像是基类对象,而是关联的派生类对象。

这就是为什么你也可以贬低原因:

string x = "hello";
object y = x;
string z = (string) y;

所有三个变量都具有相同的值 - 它们都是对同一个对象的引用。没有信息丢失。引用本身只是“获取对象的一种方式” - 变量确定哪些引用有效,并通知编译器可以通过该变量访问哪些成员,但它不会更改价值本身。

答案 3 :(得分:1)

答案是肯定的。引用具有关联类型,但引用的类型决不会影响引用所指向的实例的类型。

class A {}
class B : A {}

// Here we create an instance of B and assign it to a reference of
// type A (B is a subclass of A so this is correct). This doesn't
// change the type of B.
A a = new B();
Console.WriteLine(a.GetType()) // => prints B

// You can always assign to Object (doesn't change the type of the instance.
object o = a;
Console.WriteLine(o.GetType()) // => prints B

// And you can cast a reference to a different type, as long as they
// are compatible.
B b = (B)a;
Console.WriteLine(b.GetType()) // => prints B