一个简单判等例子的深度分析
2011-01-23 23:12
281 查看
今儿给网友讲解了一个判等的问题,看似简单,其实还是蛮有意思的:
object s = 1, t = 1;
Console.WriteLine( "s == t -> {0}", s == t );
Console.WriteLine( "s.Equals(t) -> {0}", s.Equals( t ) );
// 运行结果:
// s == t -> False
// s.Equals(t) -> True
这个结果可能会让不少同学觉得意外,那我就来给大家分析下
object s = 1, t = 1;
这里,我们看到给两个object变量做了初始化,其中伴随着装箱操作,
所谓装箱,简单地说,就是把值类型转换成引用类型的操作——object:引用类型,int:值类型
详细的可以看这篇文章:C# 装箱和拆箱
我们知道,对于值类型(Int32是值类型)的判等,是二进制的按位判等; 而对引用类型(object是引用类型)的判等,默认为判断两者内存地址是否一致。
这里的object对象,s和t分别初始化,所以地址定然不一致
可以是用object.ReferenceEquals方法验证一下:
Console.WriteLine( "ReferenceEquals(s, t) -> {0}", object.ReferenceEquals( s, t ) );
// 运行结果:
// ReferenceEquals(s, t) -> False
结果得到证实,所以 s == t自然就False了
相比而言,后面的表达式s.Equals(t)就会复杂一些
我查看了object.Equals( object )这个方法的代码(用的Reflector):
public virtual bool Equals( object obj )
{
return RuntimeHelpers.Equals( this, obj );
}
再去查看了RuntimeHelpers.Equals( object, object )的代码,最后发现这是个CLR实现的方法,没有代码···
仔细想想,关键不在RuntimeHelpers.Equals, 而在这个virtual
对了,这是个虚方法,Int32类型必然会重写这个Equals方法。也就是说,在程序中,实际调用的应该是Int32.Equals
再看Int32的Equals方法,结果就明朗了
public override bool Equals( object obj )
{
return ( (obj is int) && ( this == ( (int) obj ) ) );
}
在这里,s和t都被转换成int类型,再做值类型的按位比较,结果当然是1等于1,返回True
参考:
C# 装箱和拆箱
详解.NET中六个你必须知道的重要概念
object s = 1, t = 1;
Console.WriteLine( "s == t -> {0}", s == t );
Console.WriteLine( "s.Equals(t) -> {0}", s.Equals( t ) );
// 运行结果:
// s == t -> False
// s.Equals(t) -> True
这个结果可能会让不少同学觉得意外,那我就来给大家分析下
object s = 1, t = 1;
这里,我们看到给两个object变量做了初始化,其中伴随着装箱操作,
所谓装箱,简单地说,就是把值类型转换成引用类型的操作——object:引用类型,int:值类型
详细的可以看这篇文章:C# 装箱和拆箱
我们知道,对于值类型(Int32是值类型)的判等,是二进制的按位判等; 而对引用类型(object是引用类型)的判等,默认为判断两者内存地址是否一致。
这里的object对象,s和t分别初始化,所以地址定然不一致
可以是用object.ReferenceEquals方法验证一下:
Console.WriteLine( "ReferenceEquals(s, t) -> {0}", object.ReferenceEquals( s, t ) );
// 运行结果:
// ReferenceEquals(s, t) -> False
结果得到证实,所以 s == t自然就False了
相比而言,后面的表达式s.Equals(t)就会复杂一些
我查看了object.Equals( object )这个方法的代码(用的Reflector):
public virtual bool Equals( object obj )
{
return RuntimeHelpers.Equals( this, obj );
}
再去查看了RuntimeHelpers.Equals( object, object )的代码,最后发现这是个CLR实现的方法,没有代码···
仔细想想,关键不在RuntimeHelpers.Equals, 而在这个virtual
对了,这是个虚方法,Int32类型必然会重写这个Equals方法。也就是说,在程序中,实际调用的应该是Int32.Equals
再看Int32的Equals方法,结果就明朗了
public override bool Equals( object obj )
{
return ( (obj is int) && ( this == ( (int) obj ) ) );
}
在这里,s和t都被转换成int类型,再做值类型的按位比较,结果当然是1等于1,返回True
参考:
C# 装箱和拆箱
详解.NET中六个你必须知道的重要概念
相关文章推荐
- mybatis源码解析 - 通过一个简单查询例子分析流程
- 递归思想分析----以一个简单的例子为例
- mybatis源码解析 - 通过一个简单查询例子分析流程
- 一个简单例子的设计模式分析
- hadoop的序列化分析及一个自定义Writable的简单例子
- Log Parser分析IIS log的一个简单例子
- 一个简单的Winsock例子
- 一个简单的、基本的、完整的使用biblatex包的例子
- qt多线程一个简单的例子
- 菜鸟学习Hibernate——简单的一个例子
- MongoDB: 一个简单的配置两个shared的例子
- 一个简单的GTK的例子程序
- NS2典型例子简单分析
- 关于ColorBox使用的一个简单例子
- WCF 一步一步从入门到精通(一)建立一个简单入门的例子(适合一点不会的朋友阅读)
- Delphi 一个简单的DELPHI自定义事件的例子
- <Shader> 一个简单的设置透明度,和深度缓存的Shader
- 一个简单的例子理解C++ map, 运用map统计单词出现的次数
- 位运算实现加法的一个简单例子
- 轻松创建nodejs服务器(1):一个简单nodejs服务器例子