C#的引用类型和值类型(百思不得其解)

手抓饼加辣 2009-04-20 08:20:57
object i=99;
Console.WriteLine(i.GetType());//结果是System.Int32
i=23.55;//既然 i 是System.Int32还可以将Double类型赋值进去?
Console.WriteLine(i.GetType());//结果是System.Double
那么i到底是什么类型,是存储在堆中还是栈中?
...全文
252 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
手抓饼加辣 2010-10-13
  • 打赏
  • 举报
回复
看看一年前的帖子,不知不觉与C#相识一年半了。
手抓饼加辣 2009-04-22
  • 打赏
  • 举报
回复
分给楼上的了,谢谢各位。
楼上的可以交个朋友吗,大家互相学习。
zyk113229917 2009-04-22
  • 打赏
  • 举报
回复
记着i 是引用类型 引用类型都存放再托管堆里面.
龙宜坡 2009-04-20
  • 打赏
  • 举报
回复
所有数值类型继承自System.Type,,而System.Type又继承自System.Object;

所以会出现LZ所述情况!
tang_fu 2009-04-20
  • 打赏
  • 举报
回复
object是所有类的主类,他可以封装所有的类 当i=99的时候 其实封装的是99这个数 也就是一个整形数,这时得到的类型就是int32了
你把i赋值一个小数,当object对象封装i时 实际上时封装的是那个小数 所以类型会变成Double
feifei666888 2009-04-20
  • 打赏
  • 举报
回复
那就是父类声明,new 他的子类,返回的是他的父类对象,在应用的时候必须得强转为他对应的子类,这也就是工厂的设计模式
tabbycat 2009-04-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 a6230589 的回复:]
那么又有一个问题出现了:
class Program
{
static void Main(string[] args)
{
Person p=new Student();
Console.WriteLine(p.ToString());//此处返回的是Student类型
//那么p到底是什么类型呢?如果是Student类型为什么不能直接调用Print()方法?而是得有一个显式的类型转换才能调用:((Student)p).Print();
}
}


[/Quote]

class Person
{
public virtual void Print()
{
}
}

class Student : Person
{
public override void Print()
{
}
}

这样就可以调用Print 而且根据你new的时候,如果你Person p = new Person() 调用的是 Person的Print方法
如果你Person p = new Student() 调用的是Student 的Print方法

这是面向对象的多态
yangqidong 2009-04-20
  • 打赏
  • 举报
回复
答上面的问题
1.p是Student类型
2.程序运行起来之后才知道p是Student类型(当然也是Person),在还没运行之前,编译器只能确定p是Person 类型,所以不允许p.Print()通过编译
手抓饼加辣 2009-04-20
  • 打赏
  • 举报
回复
那么又有一个问题出现了:
class Program
{
static void Main(string[] args)
{
Person p=new Student();
Console.WriteLine(p.ToString());//此处返回的是Student类型
//那么p到底是什么类型呢?如果是Student类型为什么不能直接调用Print()方法?而是得有一个显式的类型转换才能调用:((Student)p).Print();
}
}

class Person
{

}

class Student : Person
{
public void Print()
{

}
}

希望大家集思广益!再次感谢大家
手抓饼加辣 2009-04-20
  • 打赏
  • 举报
回复
object i = 2;
object j = i;
i = 2;
Console.WriteLine(Object.ReferenceEquals(i,j));//返回false
我觉得 i.GetType()得到的是i所指向的数据的数据类型而不是i本身的类型,所以i应该是存放在堆中,第二次给i赋值同样的值,但是在堆中另外分配一块空间存放2,所以Object.ReferenceEquals(i,j))返回false
不知道我的理解对不对?
谢谢大家的帮助,希望大家继续提出自己的见解。
panyunlai 2009-04-20
  • 打赏
  • 举报
回复
学习了,c#的装箱和拆箱我不是很明白
手抓饼加辣 2009-04-20
  • 打赏
  • 举报
回复
我还是不明白,第一次接触引用类型和值类型的时候觉得自己懂了,可是随着学习的深入,发现自己其实并没有真正的理解。第一次在这里提问,谢谢大家的回答。
qiance 2009-04-20
  • 打赏
  • 举报
回复
关注
yangqidong 2009-04-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xx_mm 的回复:]
object是所有类的基类,封装所有的类
首先分配个地址存99
输出99
改变该地址的值,内存段仍是同一个地方,只是值变化了
关键是第一句话
[/Quote]

错了吧,应该不是同一个内存地址
蔡袅 2009-04-20
  • 打赏
  • 举报
回复
object是所有类的基类,封装所有的类
首先分配个地址存99
输出99
改变该地址的值,内存段仍是同一个地方,只是值变化了
关键是第一句话
zhu_chuan_hang 2009-04-20
  • 打赏
  • 举报
回复
综合1楼和3楼的答案,不知道楼主明白了没有!引用1楼的一句:“object是所有类的主类,他可以封装所有的类”
yangqidong 2009-04-20
  • 打赏
  • 举报
回复
object i=99; 发生的事情是 在堆中分配一块空间存放99,i指向这块空间,所以i GetType是int
再执行i=23.55; 发生的事情是 在堆中另外分配一块空间存放23.55,i指向这块空间 所以i GetType是double

楼主在装箱拆箱这块要加强
zyk113229917 2009-04-20
  • 打赏
  • 举报
回复
值类型存在 堆栈中 引用类型是存在于一个大概叫委托堆里的地方,object封装的时候 其实是对以个对象的引用 i是存在委托堆里的,数存在于堆栈中,i指向的是值的一个地址 应该是这样的
zyk113229917 2009-04-20
  • 打赏
  • 举报
回复
object是所有类的主类,他可以封装所有的类 当i=99的时候 其实封装的是99这个数 也就是一个整形数,这时得到的类型就是int32了
你把i赋值一个小数,当object对象封装i时 实际上时封装的是那个小数 所以类型会变成Double

111,126

社区成员

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

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

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