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

时间:2023-01-10 12:27:13

一、引言

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

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

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

二、==与Equals的区别

上面问题的运行结果为:

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

对于结果为什么是这样的呢?这主要涉及到==与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();
}

运行结果为:

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

三、typeof与GetType区别

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

           static void Main(string[] args)
{
object m1 = ;
object m2 = ;
// 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,自定义类型,不能为具体实例,否则编译器会报错

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

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

四、小结

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

[C# 基础知识系列]C#中易混淆的知识点的更多相关文章

  1. C#中易混淆的知识点

    C#中易混淆的知识点 一.引言 今天在论坛中看到一位朋友提出这样的一个问题,问题大致(问题的链接为:http://social.msdn.microsoft.com/Forums/zh-CN/52e6 ...

  2. 基础知识系列☞C#中→属性和字段的区别

    "好吧...准备写个'基础知识系列',算是记录下吧,时时看看,更加加深记忆···" 其实本来准备叫"面试系列"... 字段.属性.你先知道的哪个概念? ***我 ...

  3. 基础知识系列☞C#中数组Array、ArrayList和List三者的区别

    数组() #region 数组 //初始化方式_0:先声明再赋值 ]; weekDays_0[] = "Sun"; weekDays_0[] = "Mon"; ...

  4. [WPF 基础知识系列] —— 绑定中的数据校验Vaildation

    前言: 只要是有表单存在,那么就有可能有对数据的校验需求.如:判断是否为整数.判断电子邮件格式等等. WPF采用一种全新的方式 - Binding,来实现前台显示与后台数据进行交互,当然数据校验方式也 ...

  5. 基础知识系列☞C#中→委托

    有些.NET中的高级特性,比如:委托! 有一种怎么也搞不懂的赶脚... 博客读了好几篇,代码也动手写了,书中的一些介绍也看了, 各种搜索关于委托的,至今还处于"会用"的阶段. 该怎 ...

  6. 基础知识系列☞Abstract和Virtual→及相关知识

    转载地址→http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html 在C#的学习中,容易混淆virtual方法和abstract方法的 ...

  7. 学习javascript基础知识系列第二节 - this用法

    通过一段代码学习javascript基础知识系列 第二节 - this用法 this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascr ...

  8. 学习javascript基础知识系列第三节 - ()()用法

    总目录:通过一段代码学习javascript基础知识系列 注意: 为了便于执行和演示,建议使用chrome浏览器,按F12,然后按Esc(或手动选择)打开console,在console进行执行和演示 ...

  9. C# 基础知识系列- 3 集合数组

    简单的介绍一下集合,通俗来讲就是用来保管多个数据的方案.比如说我们是一个公司的仓库管理,公司有一堆货物需要管理,有同类的,有不同类的,总而言之就是很多.很乱.我们对照集合的概念对仓库进行管理的话,那么 ...

随机推荐

  1. SharePoint Style Library的权限问题

    Style Library是属于site collection级别的. 所以如果在某一个site中直接给某个用户设置了比如Full control的权限,这个权限信息并不会自动进入Style Libr ...

  2. 一种轻量的openresty路由设计

    在使用openresty开发接口的过程会发现一个问题,那就是接口的地址问题怎么解决,最好一个接口地址对应一个lua文件,也可以在nginx.conf 配置中使用content_by_lua 来编写接口 ...

  3. 深入讨论channel timeout

    深入讨论channel timeout Go 语言的 channel 本身是不支持 timeout 的,所以一般实现 channel 的读写超时都采用 select,如下: select { case ...

  4. 在C++遇到有些关键字或者函数被弃用的情况

    随着每一次C++的不断更新,可能都会有些函数或者关键字会被弃用,或者换成了其他的名字,这在编写代码的时候经常会碰到,碰到这种情况,可以在代码的第一行写上忽略此错误的句子,一般为: #pragma  w ...

  5. Spring AOP 前置通知

    我们使用AspectJ对Spring进行AOP操作,有两种方式,注解和XML配置方式,先在pom.xml中声明jar包 <dependencies> <dependency> ...

  6. LoadLibrary 失败的解决

    工作中遇到调用Loadlibrary 偶发失败的问题,不是必现,而且这种错误只是在程序初始化的时候出现,初始化成功后当然不会调用,而初始化也不是经常做的动作,所以查找原因起来比较麻烦,调试过程中发现有 ...

  7. 【NET CORE微服务一条龙应用】第三章 认证授权与动态权限配置

    介绍 系列目录:[NET CORE微服务一条龙应用]开始篇与目录 在微服务的应用中,统一的认证授权是必不可少的组件,本文将介绍微服务中网关和子服务如何使用统一的权限认证 主要介绍内容为: 1.子服务如 ...

  8. 3&period;Solr4&period;10&period;3目录结构

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.整个目录结构 (1)bin:是脚本的启动目录 (2)contrib:第三方包存放的目录 (3)dist:编 ...

  9. str函数

    python2: a = str(unicode类对象) #str()函数如果接收的参数是unicode类,会转换为python的defaultencoding格式,所以,如果unicode类对象是汉 ...

  10. 初步认识 LESS&comma;我要开始学习LESS啦!

    LESS 是一个流行的样式表语言,它提供了 CSS3 也未曾实现的多种功能,让您编写 CSS 更加方便,更加直观.LESS 已经被广泛使用在多种框架中 ( 例如:BootStrap).本文将介绍 LE ...