C#中易混淆的知识点

一、引言

今天在论坛中看到一位朋友提出这样的一个问题,问题大致(问题的链接为:http://social.msdn.microsoft.com/Forums/zh-CN/52e6c11f-ad28-4633-a434-fc4d09f4d23d )是这样的:

  static void Main(string[] args)
{
object m1 =1 ;
object m2 = 1; Console.WriteLine(m1==m2); Console.WriteLine(m1.Equals(m2));
Console.Read();
}

大家先不要去Visual Studio中运行这段代码,先猜猜此段代码的运行结果是怎样的,如果你猜测的结果和运行出来的结果完全是一致并且你也知道原因的话,那这篇文章下面的内容就没必要看下去了,如果你对运行出来的结果表示不理解的话,那请继续看下面内容的分析,相信看完你绝对可以解除你的疑惑。

二、==与Equals的区别

上面问题的运行结果为:

对于结果为什么是这样的呢?这主要涉及到==与Equals方法的区别的,再讲两者的区别前,大家首先要明确——C#中有两种不同的相等:引用相等和值相等。值相等意味着两个对象保护相同的值,例如,两个值为1的整数就具有值相等性;引用相等意味着要比较的不是两个对象,而是两个对象的引用,且两者引用的是同一个对象。若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,请使用 Equals(详细内容可以参考:http://msdn.microsoft.com/zh-cn/library/ms173147(v=vs.90).aspx )。下面就看看它们直接的区别:

  • ==比较的是栈内的内容,对于值类型而言,”==“比较的就是两个对象的值,除字符串(字符串类型是一个特殊情况)以外的引用类型比较的就是两个引用类型在栈内的地址
  • Equals方法是定义在Object中的虚方法,用来比较两者引用对象的值是否相等,.NET中类型就都可以重写Equals方法,例如,在.NET中string类型就重写了Equals方法,用于比较两个字符串的值是否相等,而不是字符串引用是否相等。

有了上面的理论基础,下面就具体分析上面程序为什么会是那样的结果:

  1. 首先m1,m2都是引用类型,当执行m1==m2操作时,比较的是m1与m2在栈内地址的值是否相等,即比较的是引用,因为m1和m2指向的是托管堆中1是不同的地址(这点大家可以通过在debug状态下内存窗口中查看),所以得到的结果就自然是false
  2. 对于m1.Equals(m2)比较的是m1与m2引用的值是否相等,因为它们都是引用托管堆中1,它们地址不等,但是值是相等的,都是1,所以返回为true。

下面用一道题目测试大家的掌握程度(也是为了进一步加深理解)

static void Main(string[] args)
{
string str1 = "ZhangSan";
string str2 = "ZhangSan";
string str3 = new string(new char[] { 'z', 'h' });
string str4 = new string(new char[] { 'z', 'h'});
Console.WriteLine("str1 == str2 " + (str1 == str2).ToString());
Console.WriteLine("str1 Equals str2 " + str1.Equals(str2));

Console.WriteLine("str3 == str4 " + (str3 == str4).ToString());
Console.WriteLine("str3 Equals str4 " + str3.Equals(str4));

Console.Read();
}

运行结果为:

三、typeof与GetType区别

从上面那个问题中,我又联系到了typeof与GetType的区别,所以这里就一起总结下,首先我还是由一个程序来引出它们的区别:

           static void Main(string[] args)
{
object m1 = 1;
object m2 = 1;
// ValueType是引用类型,因为它是类,所以返回为false
Console.WriteLine(typeof(ValueType).IsValueType);
Console.WriteLine(m1.GetType().IsValueType);
Console.Read();
}

要想弄明白上面的运行结果,首先我们应该理解typeof与GetType的区别(之前我认为两个的都是一样的,这是一个误区),具体的区别为:

  • typeof 是运算符,而 GetType()是方法
  • typeof 获得类型的System.Type对象,GetType()获得当前实例的Type,
  • GetType()是基类System.Object的方法,只有建立了一个实例之后才能够被调用
  • typeof的参数只能是int, string, class,自定义类型,不能为具体实例,否则编译器会报错

知道它们的区别之后,结果也就很容易得到了,上面程序的运行结果为:

四、小结

这篇文章主要是记录下自己在回答问题时所学到的内容,也希望对有同样疑惑的朋友有所帮助。

作者:Learning Hard
提示:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
如果对文章有任何问题,都可以再评论中留言,我会尽可能的答复您,谢谢你的阅读

C#中易混淆的知识点的更多相关文章

  1. [C# 基础知识系列]C#中易混淆的知识点

    一.引言 今天在论坛中看到一位朋友提出这样的一个问题,问题大致(问题的链接为:http://social.msdn.microsoft.com/Forums/zh-CN/52e6c11f-ad28-4 ...

  2. lua中易混淆函数

    lua中易混淆的函数 ipairs和pairs: ipairs只能顺序遍历table,遇到key不是数字就会退出 pairs可以遍历table中所有元素 ----------------------- ...

  3. JavaScript中易混淆的DOM属性及方法对比

    JavaScript中易混淆的DOM属性及方法对比 ParentNode.children VS Node.prototype.childNodes ParentNode.children:该属性继承 ...

  4. jQuery中易混淆知识点总结(持续更新)

    find()与children() <body> <ul class="level-1"> <li class="item-i"& ...

  5. 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结

    概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...

  6. Java多线程中易混淆的概念

    概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...

  7. iOS中容易混淆的知识点(持续更新中)

    1.成员变量和属性的区别 @interface Person : NSObject { NSString *_sex; } @property (nonatomic, copy) NSString * ...

  8. SQL Server中易混淆的数据类型

    1)char.varchar.text和nchar.nvarchar.ntextchar和varchar的长度都在1到8000之间,它们的区别在于char是定长字符数据,而varchar是变长字符数据 ...

  9. .NET 中易混淆的概念(Delegate vs Event)

    事件(event)是一个非常重要的概念,我们的程序时刻都在触发和接收着各种事件:鼠标点击事件,键盘事件,以及处理操作系统的各种事件.所谓事件就是 由某个对象发出的消息.比如用户按下了某个按钮,某个文件 ...

随机推荐

  1. oracle处理节点之间的父子关系

    通常当与树的结构之间的关系处理,这是一个很复杂的事情,我们可以通过程序代码去逐层遍历父或子节点,这样做的缺点是很明显,效率不高,操作复杂性是比较大的.而当我们使用Oracle当数据库,我们可以有一个简 ...

  2. Linux开发环境的搭建和使用——Linux本必备软件SSH

    SSH 至 Secure Shell 缩写.由 IETF 网络工作组(Network Working Group)开发:SSH 以建立应用层和传输层安全协议中的基础上. SSH 是眼下较可靠,专为远程 ...

  3. Yii Framework2.0开发教程(10)配合mysql数据库实现用户登录

    1.首先在mysql创建一个存用户的表格 create table test_user ( user_id bigint(20) unsigned not null auto_increment co ...

  4. mysql5.6.16绿色版配置、运行

    原文:mysql5.6.16绿色版配置.运行 1.从该地址http://dev.mysql.com/downloads/mysql/中选择windows的版本,选择下载. 2.将下载的压缩包解压. 3 ...

  5. poj 3026 Borg Maze (bfs + 最小生成树)

    链接:poj 3026 题意:y行x列的迷宫中,#代表阻隔墙(不可走).空格代表空位(可走).S代表搜索起点(可走),A代表目的地(可走),如今要从S出发,每次可上下左右移动一格到可走的地方.求到达全 ...

  6. Eclipse生成jsp 如何将GB18030 改成默认UTF-8

    前两天面试被问到了struts的问题,好久没用了准备复习下,用eclipse创建一个maven项目的时候发现创建的jsp文件都是GB18030编码的,如何更改为UTF-8呢,其实很简单,给各位分享一下 ...

  7. ASP.Net TextBox控件只允许输入数字

    原文:ASP.Net TextBox控件只允许输入数字 1.1.在Asp.Net TextBox 控件的 OnKeyPress 事件中指定输入键盘码必须为数字: <asp:TextBox ID= ...

  8. ORACLE经常使用的命令

    一个.ORACLE启动和关机 1.在独立环境中 要启用或禁用ORACLE该系统必须切换到ORACLE用户,例如以下 su-oracle a.启动ORACLE系统 oracle>svrmgrl S ...

  9. SQL Server 远程链接服务器详细配置

    原文:SQL Server 远程链接服务器详细配置[转载] http://hi.baidu.com/luxi0194/blog/item/a5c2a9128a705cc6c2fd7803.html - ...

  10. Repository 仓储

    Repository 仓储 写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这 ...