C#.Net一百零一夜(第一夜)

  一千零一夜的童话,使得童年的我,朦胧的开始了解世界,我也希望我的系列能够让初次踏上.Net这片沃土的您,能够有个坚强的臂膀,就如同您在知识海洋中遨游的那片孤舟,您无须知道您从那里出发,也无须知道您将向何而去,您只知道有这么一个日子,知识的彼岸将被您踏在脚下!

第一夜:
  目的:字符串相等的比较。
  陷阱:==运算符与Equal方法的调用的结果大多情况是相同的,但也只是大多的情况而已。
  下面是我通过Reflector反编译类库查看到的,String类对==与!=都进行了重载。
  
public static bool operator ==(string a, string b)
{
  
return string.Equals(a, b);
}


public static bool operator !=(string a, string b)
{
  
return !string.Equals(a, b);
}
  当比较对象的2个类型都是String时,它们是没有区别的。那么我们再做个试验。
  如下代码分为2个部分。
  试验1:
static void Main(string[] args)
{
    
string strA    = "hatita";
    
string strB    = "hatita";

    Console.WriteLine(strA 
== strB);
    Console.WriteLine(strA.Equals(strB));

    
object objA    = strA;
    
object objB = strB;

    Console.WriteLine(objA 
== objB);
    Console.WriteLine(objA.Equals(objB));


    Console.WriteLine(
"***************************************************")


    
string strC = new string(new char[] {'h','a','t','i','t','a'});
    
string strD = new string(new char[] {'h','a','t','i','t','a'});
    Console.WriteLine (strC
==strD);
    Console.WriteLine (strD.Equals(strD));
    
    
object objC = strC;
    
object objD = strD;
    Console.WriteLine (objC
==objD);
    Console.WriteLine (objC.Equals(objD));
}

  输出结果:

   客官您看到那个false的输出结果没有,两段几乎相似的代码为何带来不同的结果?
   让我们看下一个试验!
   试验2:让我们看一下它们在内存中的位置!
unsafe static void Main(string[] args)
{
    
string strA    = "hatita";
    
string strB    = "hatita";

    
string strC = new string(new char[] {'h','a','t','i','t','a'});
    
string strD = new string(new char[] {'h','a','t','i','t','a'});

    
fixed(char* cPoint1 = strA)
    
{
        IntPtr i 
= (IntPtr)cPoint1;
        Console.WriteLine(i.ToInt32());
    }


    
fixed(char* cPoint1 = strB)
    
{
        IntPtr i 
= (IntPtr)cPoint1;
        Console.WriteLine(i.ToInt32());
    }


    Console.WriteLine(
"***************************************************");

    
fixed(char* cPoint1 = strC)
    
{
        IntPtr i 
= (IntPtr)cPoint1;
        Console.WriteLine(i.ToInt32());
    }


    
fixed(char* cPoint1 = strD)
    
{
        IntPtr i 
= (IntPtr)cPoint1;
        Console.WriteLine(i.ToInt32());
    }
    
}



输出结果:


    看了结果客官您应该很清楚了吧!
    strA和strB根本就是指向同一个内存块!所以在使用Ojbect==的时候,直接判断引用相同,返回True。
    而strC和strD,在使用Ojbect==的时候,因为比较的类型是object,无法使用已重载String==,然后又引用不相同,所而返回的是False。
    而至于为什么相同的String会造成引用的不同,呵呵,那就是另外一篇新随笔了。
 
    我个人推荐是:对于几乎所有引用类型,当您希望判断对象性能相等性而不是对象引用一致性时,请使用 Equals,当然String这个特殊的引用类型除外,对字符串使用==增加了代码的可读性(至少我觉得比较清爽^.^,但请切记运算符两段就必须是String类型的表达式!
 
    结论:为了钱包着想,小心使得万年船!



    ①如未特别说明,本人所发表的技术文章都为呕心沥血原创之作, 任何人引用都请注明出处,并包含本声明,谢谢。
    ②本文章有缺式之处,请及时指出,谢谢!
    ③如对文章不屑一顾,那么您的漫骂就是我的动力。
    ④向无名的开源英雄致敬!
posted on 2006-01-22 01:03  悠远的风景  阅读(2737)  评论(13编辑  收藏  举报