关于装箱拆箱的一点疑问

woailihuan2 2012-04-14 09:11:25
各位高手,小弟有一事不明。这是小弟写的代码
int i = 56;
object z = i; //装箱
object m = i; //装箱
Console.WriteLine("{0},{1},{2}", i, z, m);
Console.WriteLine(object.Equals(z, m));
Console.ReadKey();
为什么 Console.WriteLine(object.Equals(z, m));这句代码返回的是true。装箱不就是新创建一个object类型,然后把值赋值给这个引用类型,他们两个指向地址都不一样为什么相等?
...全文
147 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
woailihuan2 2012-04-14
  • 打赏
  • 举报
回复
明白了!谢谢高手们!给你们添麻烦了!
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
装箱不就是新创建一个object类型,然后把值赋值给这个引用类型
[/Quote]

其实应该类似于这样说:装箱是首先创建了(复制了)数值对象,然后再把对象赋值给(声明为)object类型的变量来引用。
threenewbee 2012-04-14
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
装箱和拆箱的本质并不是把值类型变成引用类型.
而是用一个引用类型的对象把值类型包装一下,真正到了使用的地方还是要拆箱的.
就是说,两个箱子,里面是一样的东西.你使用的时候是用的里面的东西,根本不会感觉到箱子的存在.但确实是两个箱子.
[/Quote]
就是这样,lz你明白了么?
cheng2005 2012-04-14
  • 打赏
  • 举报
回复
装箱和拆箱的本质并不是把值类型变成引用类型.
而是用一个引用类型的对象把值类型包装一下,真正到了使用的地方还是要拆箱的.
就是说,两个箱子,里面是一样的东西.你使用的时候是用的里面的东西,根本不会感觉到箱子的存在.但确实是两个箱子.
  • 打赏
  • 举报
回复
如果你有一点自学.net源码的知识,很多时候不必在csdn来问基本的问题了。
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
装箱不就是新创建一个object类型,然后把值赋值给这个引用类型,他们两个指向地址都不一样为什么相等?
[/Quote]

“创建一个类型”?哪有这种概念。你既然自己的都不敢说是“创建一个新对象”,有怎么可能断言说“他们两个指向的地址都不一样”?




另一方面,object类型上的Equals定义
public static bool Equals(object objA, object objB)
{
return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
}

而Int32类型重写了object父类的bool Equals(object obj)方法,在多态中它会执行Int32的代码,而不是object的。

不依据.net源代码来“学”.net,就等于瞎子摸象,很纠结。
种草德鲁伊 2012-04-14
  • 打赏
  • 举报
回复
你可以看一下框架的源代码
值类型的equals方法实际上是对每个字段的值进行比较。
woailihuan2 2012-04-14
  • 打赏
  • 举报
回复
高手!求解释!谢谢各位高手,解答一下9楼的问题!谢谢各位!
woailihuan2 2012-04-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
……
[/Quote]
我看了,结果执行的第一个是False 一个是true
难道对于值类型和引用类型,Object.Equals()方法执行不一样吗?
求解释!
threenewbee 2012-04-14
  • 打赏
  • 举报
回复
归根到底,int是值类型的,你无论怎么用object,它都是int。

你没有正确理解“装箱拆箱”是什么。上一个贴我是白说了。
threenewbee 2012-04-14
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
User u1 = new User() { ID = 1, Name = "A" };
User u2 = new User() { ID = 1, Name = "A" };
Console.WriteLine(object.ReferenceEquals(u1, u2));
Console.WriteLine(object.Equals(u1, u2));
}
}
struct User
{
public int ID { get; set; }
public string Name { get; set; }
}
}


那好,你再看这个。
woailihuan2 2012-04-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

上面的类型已经重载equals方法了。
[/Quote]
小弟不懂!还望高手解释清楚!
种草德鲁伊 2012-04-14
  • 打赏
  • 举报
回复
上面的类型已经重载equals方法了。
woailihuan2 2012-04-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

object.Equals(z, m)不是比较地址。
ReferenceEquals才是。
[/Quote]
那为什么用object.Equls()方法比较引用类型时代码如下:
先声明一个类:
class MyType
{
public int Data;
}
Main方法中的代码:
MyType m1 = new MyType();
MyType m2 = new MyType();
m1.Data = m2.Data = 1990;
Console.WriteLine(object.Equals(m1, m2));
Console.ReadKey();
输出值:false
这是为什么?
threenewbee 2012-04-14
  • 打赏
  • 举报
回复
小白太多。

我还是详细说说:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
User u1 = new User() { ID = 1, Name = "A" };
User u2 = new User() { ID = 2, Name = "B" };
Console.WriteLine(object.ReferenceEquals(u1, u2));
Console.WriteLine(u1 == u2);
Console.WriteLine(object.Equals(u1, u2));
Console.WriteLine(u1.Equals(u2));
}
}
class User
{
public int ID { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
return true;
}
}
}


False
False
True
True
Press any key to continue . . .

注意这4个比较的不同。
neptunegm 2012-04-14
  • 打赏
  • 举报
回复
z和m显然指向同一个引用
你不妨再添加一行,看看结果:


object o3=56;

Console.WriteLine(object.Equals(z,o3));

threenewbee 2012-04-14
  • 打赏
  • 举报
回复
object.Equals(z, m)不是比较地址。
ReferenceEquals才是。

110,535

社区成员

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

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

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