日期:2014-05-17  浏览次数:21113 次

C#是不是不能把基类对象强转成它派生类对象

 

转载请标明是引用于 http://blog.csdn.net/chenyujing1234

有补充的,请大家指出!

 

 

最近在论坛上看到有网友问到C#中对象强转的问题,自己虽然接触过C#,但对这个特性还是第一次接触,所以这里找到一些资料与大家一起分享。

一、代码
class Program
{
  static void Main(string[] args)
  {
  A a = new A();
  B b =new B();
  b.a = 300;
  b.b = 20;
  B e = a.Clone() as B;//这里会运行错误 但是变成b.clone() as B 就会正常
  System.Console.WriteLine(e.a);
  }
}

public class A : ICloneable   
{
  public A()
  {
    
  }

  public int a=200;

  #region ICloneable 成员
  public virtual object Clone()
  {
  	return MemberwiseClone();
  }
  #endregion

}

public class B:A
{
  public int b = 10;

  public B():base()
  {
    
  }
  public override object Clone()
  {
  	B c= base.Clone() as B;//为什么这里可以把基类变成派生类?????????
  	c.b = 100;
  	return c;
  }
}


二、解释

1、解释“B e = a.Clone() as B;//这里会运行错误 但是变成b.clone() as B 就会正常”

你实例化是二个对象,而父类中没有关于子类的对象相关的内存,无法转

这段代码代码的分析很简单:
a.Clone()得到的仍然是一个A类型的对象。A是基类,没有B类的内存,所以基类是无法强制转换成派生类的。
b.Clone()得到的就B类型的对象了。所以可以AS B。

给你一个例子:

A a = new A();
B b = new B();
A a2 = b; //这是可以的。
B b2 = a2 as B; //这种强制转换也是可以成功的。


2、解释“B c= base.Clone() as B;//为什么这里可以把基类变成派生类????????? ”

这是因为你实例化的对象本身就是B,B相当包含A存在.所以可以转。

 


变量a不论你声明为什么类型,它指向一个A类对象。变量b不论你声明什么类型,它指向一个B类对象。不是说“可以把基类变成派生类”这种把类型类型和对象本身混淆起来,而是对象b既“是”A类对象也“是”B类对象,也就是说
  if(b is A && b is B)
  return true;
你可以试试看,这返回true。