从内存分配角度看类型转换

sinzou1 2010-01-24 04:18:31

以前看过c++,对类型转换都是从内存分配的角度理解的。
开始c#也从内存分配理解的,但越搞越接近IL,接近c#编译原理,限于知识有限,归纳不出它的转换规则(才知道c++当时也学的是一知半解)。查过些书,但都没有全面的讲解的。感觉走进了误区。退而求其次,不要求从内存分配上求知,只希望给出使用级别上,c#的转化规则,要全面的。

还有类型转换与类型兼容之间的关系,is和 as关键字的用法 (“兼容”就是对象是该类型或者是派生于该类型,这种表象 简单的回答,也就不用回答了)

还有拆箱和装箱中类型的转换

个人认为,以上涉及的类型转换等问题 其本质上都是一样的 或者说是同一个问题
我也查了很多书,只是简单的说什么 派生类隐式的转化为派生类之类的,就免于留言吧!

高手可以回答下 表面的类型转换在底层内存上的变化机制
为了便于回答,下面是书上的例子,有真知灼见的哥们可以参考着回答下。

class B
{

}
class D:B
{

}
static void Main(string[] args)
{
OK 不能通过编译 执行异常
object o1 = new object(); *
object o2 = new B(); *
object o3 = new D(); *
object o4 = o3; *
B b1 = new B(); *
B b2 = new D(); *
D d1 = new D(); *
B b3 = new object(); *
D d2 = new object(); *
B b4 = d1; *
D d3 = b2; *
D d4 = (D)d1; *
D d5 = (D)b2; *
D d6 = (D)b1; *
B b5 = (B)o1; *
B b6 = (D)b2; *
}

这个问题烦了我很多天了,希望大家能给出全面的讲解,或在什么地方有类似详细全面的理解!!!
初涉.NET不久,这块知识点周围同学都觉得理所当然,没什么问题。可我偏偏过不去这个坎,他们又解答不了我的问题。应该是c++留下来的毛病,过分关注内存。但我总得在一定层面上要理解后识记住他的用法啊,不想死记硬背。
拍拖了,小弟不甚感激!
...全文
219 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2010-01-25
  • 打赏
  • 举报
回复
不做过多的讨论了

自己找本《你必须知道的.net》看看就成,人家用了一本书的篇幅讲这个,也算深入浅出了。我们就不多费笔墨了

如果让我解释我只能说: 东西没变,变的是你戴的镜片组(type),object镜片是红的,你自己镜片是黄的,ok 你现在看到啥了,红+黄=橙(东西还是那个东西,不过他现在你眼里是橙的)
如果去掉你自己的黄镜片(object a=(object)new B()),你现在看到啥了,他成红色了(东西还是那个东西,不过你戴的是红镜片)

再加上黄镜片 B=(B)a;(现在呢 红+黄=橙,他又回橙色了)
xxxccc5678 2010-01-25
  • 打赏
  • 举报
回复
楼主 看下

http://www.enet.com.cn/eschool/video/c/17.shtml 视频中 第4分钟17秒那个图

也许有帮助
vrhero 2010-01-25
  • 打赏
  • 举报
回复
对引用类型来说,内存唯一发生的变化就是创建了一个新引用...实例是实例,声明是声明,转换的仅仅是类型,实例并没有变...

对值类型来说复杂一些,不过就和C++很类似了,在栈上重新分配内存...而对装拆箱来说最复杂,但谈论已经非常久非常多其实也最清楚...
reejayyang 2010-01-25
  • 打赏
  • 举报
回复
学习
sinzou1 2010-01-25
  • 打赏
  • 举报
回复
算了。哪位大哥能把上面给的例子全面解释下???!!!
xxxccc5678 2010-01-25
  • 打赏
  • 举报
回复
例:
A包含B
A是B的子类 :内存中开辟一个A 把B复制进A里
A可以转成B : 指向A里面的B而已

object是所有的父类 可以理解成所有实例中都包含object吧

我在书上看的 我是初学者
sito_hongta 2010-01-25
  • 打赏
  • 举报
回复
等大牛來解釋~~
cnzdgs 2010-01-25
  • 打赏
  • 举报
回复
变量类型分为值类型和引用类型。值类型派生自System.ValueType,变量中直接储存相应的值,赋值操作是传递变量的值;引用类型变量中储存的是对象的引用,也就是内存地址,相当于C++中的指针变量,赋值操作是传递对象的引用(地址)。你这里所提到的都是引用类型。
在传递对象的引用时,如果类型不同则需要进行转换,一种类型可以隐式转换为其基类型,反之则需要显式转换,这种转换只是形式上的,对象本身并不发生任何变化。对象内部记录着该对象实际的类型,在进行转换时会对类型进行检查,变量可以保存其同类型或派生类型的对象的引用,如果要保存其它类型(包括其基类型)的对象的引用,则会产生异常。
sinzou1 2010-01-24
  • 打赏
  • 举报
回复
自己ding...
sinzou1 2010-01-24
  • 打赏
  • 举报
回复
不是吧,这问题很难啊!
ysz89757 2010-01-24
  • 打赏
  • 举报
回复
太难了,学习下
ouc_ajax 2010-01-24
  • 打赏
  • 举报
回复
当实例化D的对象时候,内存分配方式为:先分配B类空间(就和初始化一个B对象一样),然后再分配一个D对象
子类里有一个区域放的父类的实例,子类内存区里有一个this指针,指向了这个内存区里包括的父类实例区,当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.
而c#采用迟绑定技术,执行的时候会执行相应的函数。

至于类型转换,编译期间是没有实际的类型转换,只是c#语言是强类型语言,对安全要求看的很重,进行了一些强制的规定,B b2 = new D(); //这种子类对象赋给父类对象是肯定可以通过编译的。而反过来肯定不行,相反,如果两个类之间没有任何关系,如果我们定义了强制转换函数,编译器也会智能的通过编译。
B b3 = new object(); //编译器会认为肯定不能把object对象给B类型对象,因此编译出错!把子类的给父类也同样通不过编译。

真要好好了解内存分配,还是好好看看c++方面的书,c#是从c++基础上过来的,感觉除了单继承不一样外,其余c++和c#的内存分配方式基本还是一致的。

个人所想,有误勿怪!

lovexilove 2010-01-24
  • 打赏
  • 举报
回复
up

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧