现在的位置: 首页 > 综合 > 正文

C#中的equals与==的比较

2013年12月05日 ⁄ 综合 ⁄ 共 2960字 ⁄ 字号 评论关闭

 

在任何语言中,String都无疑是非常特殊的一种数据类型。C#中也是如此。

string是System.String的alias。

alias用using声明,用法如下

using[alias=]class_or_namespace;

2

string是个独特的基本数据类型,它是基本数据类型中唯一的引用类型。作为基本数据类型,字符串可以声明为常量,但是却放在堆中。

字符串是唯一具有可变长度的基本数据类型

3

.NETFramework的String类型是不可变的。

不可改变的一个优点是它是线程安全的。

如果系统在编译时知道一个字符串中的字符是什么,就会内置这个字符串。被内置的字符串可以是一个常量,也可以不是。

把String定义为不可改变,它的表现像一个值类型,但实际上仍然是引用类型。

时刻记住的一点是:

任何对String的修改都会创建一个新String对象。

比如String.Replace(),String.ToLower()等待。

Const是初始化字符串最有效的方法,因为它涉及的IL指令最少。

4

String虽然是reference类型,但其分配却可以不使用new表达式,Stringobject的初始化可采用“适用于value型别”的语法。如:

stringstr="TestString";

此外:

C#Primer中文版(StanleyB.Lippman,侯捷/陈硕合译)中有这样一句:“如果声明的是Localarray,有一个简短表示法可以使我们不必再明确调用new表达式。”

虽然我对Localarray的确切定义不甚了解,但对于接下来的用法还是比较熟悉的。

string[]m_message=

{

"Hi,Pleaseenteryourname:",

"Oops,Invalidname,Pleasetryagain:",

//此处的","用不用都可

}

5

String虽然是reference类型,但是operators(==and!=)却定义为比较二者的值,而不是引用

一个来自MSDN上的例子。

stringa="hello";

stringb="h";

b+="ello";//appendtob

Console.WriteLine(a==b);

//output:True--samevalue

Console.WriteLine((object)a==b);//False--differentobjects

6

String是reference类型没有错,但我试了以下代码后却让我感觉到String的特殊。

classClass1

{

staticvoidMain(string[]args)

{

Class1c=newClass1();

stringstr="123";

c.Change(str);

Console.WriteLine(str);

}

privatevoidChange(strings)

{

s="456";

}

}

结果却是:

123

做了小改动之后:

classClass1

{

staticvoidMain(string[]args)

{

Class1c=newClass1();

stringstr="123";

c.Change(refstr);

//加上ref关键字

Console.WriteLine(str);

Console.Read();

}

privatevoidChange(refstrings)

//加上ref关键字

{

s="456";

}

}

输出结果是:

456

7

 

对于值类型,如果对象的值相等,则相等运算符 (==) 返回 true,否则返回 false。对于string 以外的引用类型,如果两个对象引用同一个对象,则 == 返回 true。对于 string 类型,== 比较字符串的值。

==操作比较的是两个变量的值是否相等

equals()方法比较的是两个对象的内容是否一致.equals也就是比较引用类型是否是对同一个对象的引用。
static void Main()

    {       

        string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });

        string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });        //未开辟新内存空间,使用的还是a的内存空间,相当于a对象,它们两个在堆中使用的是一个内存空间.当建立b时,先在堆中查找有没有 所需要的内容,有的话,就直接指向,没有的话就新建一个
         Console.WriteLine (a==b);                                                //输出true,

        Console.WriteLine (a.Equals(b));                                           //输出true,

         object c = new object();

        object d = new object();      //在堆中开辟新的内存空间,对象内容与c是不同的,与字符串对象不同,这样的对象建立的时间,不用在堆中查找有没有相同的内容,直接在堆内存中开辟一块新的内存空间.
        Console.WriteLine(c == d);            //输出false,因为cd它们两个在栈中的内容不一样

        Console.WriteLine(c.Equals(d));      
//输出false,因为虽然建立cd时所用的语法是一样的,但终究它们不是相同的对象,只有用object d=c;这样才是相同的对象

   object e = new object();

         object f = e;                     新建立对象f,这时把已经有的对象赋给f,这样f就不会在堆内存中开辟新的内存空间,而是直接把,e的引用传给f,也就是把e在栈中的引用值,传到f在栈中的内存中.这样它们就同时指向了相同的椎内存.
        Console.WriteLine(c == d);

        Console.WriteLine(c.Equals(d));


}

说明equals比较的是堆中的内容,也就是两个对象的内容;

而==比较的是值,也就是栈中的内容.

总结,用string 建立新对象时,会在内存中查找有没有相同的内容,有的话,直接把新建立的对象指过去,没有的话,就在堆中开辟新的内存空间.这个string对象还是比较特殊的.

而用其它类新建立的对象,就没有在堆中查找的步骤,直接在堆内存中开辟一块新的内存空间.当然不包括下面这种形式:   

object e = new object();

object f = e;

把新建立的对象以原有的对象赋值,这样就不会在堆内存中开辟新的空间.

以上内容是操作中得到的,正确与否,有待进一步考察.

(在java中好像以下是建立不相同的对象,也就是说在堆中的不共用内存,当然在栈内存中保留的引用也不相同,但彼此的堆内容是相同的,都是字符串"abc".       

string a = new string("abc");

string b = new string("abc")

抱歉!评论已关闭.