分享

C# Object Equals 简介2

 hqpek 2019-02-10

简介1中详细的介绍了值类型和引用类型的Equals比较。今天来谈一谈String类型。

1. String细节科普

按照惯例,科普一下String引用类型知识:

String驻留(不变性):

string a="123";
  • 1

实际上相当于在堆中开辟了一块内存用来存放"123"。由于在程序中"123"字符串会频繁使用,C#为了优化性能,就设计了一个表,表结构类似于Dictionary类的key,value形式,key:存放值,value:存放值得引用。当我们在程序用再次使用"123"这个字符串时,C#就会在这个表中进行匹配,如果找到了,就把value所存的引用地址返回给所声明的变量,这样就不用重新开辟内存。如果没有找到,则new一个新内存,存放值,并且以key,value的形式存放在该表中,方便下次重用。

String中的特殊情况
当然,并不是所有的情况都适用于String驻留,其中有一种特殊的是字符串拼接
比如:

string a="1";
a+="23";   
  • 1
  • 2

一旦拼接字符串,在指令级别所执行的代码与string驻留是不一样的,string驻留在IL(中间语言)中执行,类似于strloc的代码,拼接则不同有兴趣的同学自己查一下IL。
而一旦拼接字符串,就会在堆中开辟新的内存,地址也是新的地址,这块新内存的值跟string所存储的那张表就没有任何关系了(执行的指令不一样,根本就不会去那张表进行数据匹配),所以,千万不要频繁拼接字符串!!!
比如说变量a,先开辟了一块内存里面存放1,然后在开辟一块新内存存放123,每一次拼接必然开辟新内存存储,极为消耗内存。

2. String 实战

数据类型比较依据表:


== equals ReferenceEquals
值类型 地址
引用类型(除String) 地址 地址 地址
String 地址
private static void StringEqualsTest2()
        {
            string a = "123";
            string b = "123";
            string c = "1";
            c += "23";
            string d = "12";
            d += "3";

            //值比较
            Console.WriteLine(a == b);
            Console.WriteLine(a == c);
            Console.WriteLine(c == d);
            Console.WriteLine(a.Equals(b));
            Console.WriteLine(a.Equals(c));
            Console.WriteLine(c.Equals(d));
            Console.WriteLine(string.Equals(a,b));
            Console.WriteLine(string.Equals(a,c));
            Console.WriteLine(string.Equals(c,d));

            Console.WriteLine("---------------------------");

            //内存地址比较
            Console.WriteLine(object.ReferenceEquals(a, b));
            Console.WriteLine(object.ReferenceEquals(a, c));
            Console.WriteLine(object.ReferenceEquals(c, d));
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

执行结果如图:
string简介

  • 分割线以上:
    解释:是因为string类重写了==,!=,Equals方法,使其像值类型一样,只比较所存的值
  • 分割线以下:
    解释:第一个True是因为string驻留,其他两个False是因为拼接字符串导致。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多