当前位置: 首页 > news >正文

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

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

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

None.gif
None.gif
public   static   bool   operator   != ( string  a,  string  b)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
return !string.Equals(a, b);
ExpandedBlockEnd.gif}
  当比较对象的2个类型都是String时,它们是没有区别的。那么我们再做个试验。
  如下代码分为2个部分。
  试验1:
None.gif static   void  Main( string [] args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
string strA    = "hatita";
InBlock.gif    
string strB    = "hatita";
InBlock.gif
InBlock.gif    Console.WriteLine(strA 
== strB);
InBlock.gif    Console.WriteLine(strA.Equals(strB));
InBlock.gif
InBlock.gif    
object objA    = strA;
InBlock.gif    
object objB = strB;
InBlock.gif
InBlock.gif    Console.WriteLine(objA 
== objB);
InBlock.gif    Console.WriteLine(objA.Equals(objB));
InBlock.gif
InBlock.gif
InBlock.gif    Console.WriteLine(
"***************************************************")
InBlock.gif
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
string strC = new string(new char[] dot.gif{'h','a','t','i','t','a'});
ExpandedSubBlockStart.gifContractedSubBlock.gif    
string strD = new string(new char[] dot.gif{'h','a','t','i','t','a'});
InBlock.gif    Console.WriteLine (strC
==strD);
InBlock.gif    Console.WriteLine (strD.Equals(strD));
InBlock.gif    
InBlock.gif    
object objC = strC;
InBlock.gif    
object objD = strD;
InBlock.gif    Console.WriteLine (objC
==objD);
InBlock.gif    Console.WriteLine (objC.Equals(objD));
ExpandedBlockEnd.gif}

None.gif

  输出结果:
3.JPG

   客官您看到那个false的输出结果没有,两段几乎相似的代码为何带来不同的结果?
   让我们看下一个试验!
   试验2:让我们看一下它们在内存中的位置!
None.gif unsafe   static   void  Main( string [] args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
string strA    = "hatita";
InBlock.gif    
string strB    = "hatita";
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
string strC = new string(new char[] dot.gif{'h','a','t','i','t','a'});
ExpandedSubBlockStart.gifContractedSubBlock.gif    
string strD = new string(new char[] dot.gif{'h','a','t','i','t','a'});
InBlock.gif
InBlock.gif    
fixed(char* cPoint1 = strA)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IntPtr i 
= (IntPtr)cPoint1;
InBlock.gif        Console.WriteLine(i.ToInt32());
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
fixed(char* cPoint1 = strB)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IntPtr i 
= (IntPtr)cPoint1;
InBlock.gif        Console.WriteLine(i.ToInt32());
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    Console.WriteLine(
"***************************************************");
InBlock.gif
InBlock.gif    
fixed(char* cPoint1 = strC)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IntPtr i 
= (IntPtr)cPoint1;
InBlock.gif        Console.WriteLine(i.ToInt32());
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
fixed(char* cPoint1 = strD)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IntPtr i 
= (IntPtr)cPoint1;
InBlock.gif        Console.WriteLine(i.ToInt32());
ExpandedSubBlockEnd.gif    }
    
ExpandedBlockEnd.gif}

None.gif


输出结果:
4.JPG

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



    ①如未特别说明,本人所发表的技术文章都为呕心沥血原创之作, 任何人引用都请注明出处,并包含本声明,谢谢。
    ②本文章有缺式之处,请及时指出,谢谢!
    ③如对文章不屑一顾,那么您的漫骂就是我的动力。
    ④向无名的开源英雄致敬!

转载于:https://www.cnblogs.com/hatita/archive/2006/01/22/321526.html

相关文章:

  • 华为成功破解磁悬浮列车WCDMA无缝覆盖难题
  • 数据结构-翻牌游戏
  • TreeView初始化,返回节点值的方法(转)--收藏
  • ASP.NET中的ViewState
  • 通过XMLHTTP发送请求
  • 由一段游戏层代码想到的
  • java面试题及答案
  • 命名成为了我写程序加大工作量事情之一
  • [转载]狂人Wolfram及其新科学
  • 使用线程,防止当前程序被阻塞
  • 删除重复的记录(SQL语句)
  • 面试技巧
  • zt 《三国志·步幸传》 [马伯庸]
  • 权限管理
  • Access中统计处理.
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Electron入门介绍
  • es6
  • go语言学习初探(一)
  • Spring Boot MyBatis配置多种数据库
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • Webpack 4x 之路 ( 四 )
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 关于for循环的简单归纳
  • 理清楚Vue的结构
  • 漂亮刷新控件-iOS
  • 三栏布局总结
  • 我的业余项目总结
  • 主流的CSS水平和垂直居中技术大全
  • 回归生活:清理微信公众号
  • 交换综合实验一
  • "无招胜有招"nbsp;史上最全的互…
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #if #elif #endif
  • (八十八)VFL语言初步 - 实现布局
  • (多级缓存)多级缓存
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • .Net Web项目创建比较不错的参考文章
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .net中的Queue和Stack
  • @Autowired自动装配
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [Android Pro] Notification的使用
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [C++]C++入门--引用
  • [exgcd] Jzoj P1158 荒岛野人
  • [ffmpeg] 定制滤波器
  • [G-CS-MR.PS02] 機巧之形2: Ruler Circle
  • [Kubernetes]2. k8s集群中部署基于nodejs golang的项目以及Pod、Deployment详解
  • [LeetCode]-Integer to Roman 阿拉伯数字转罗马数字
  • [math]判断线段是否相交及夹角