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

誉重网站建设境外做网站网站

誉重网站建设,境外做网站网站,有没有做淘宝网站的,抖音优化推广string是一种很特殊的数据类型#xff0c;它既是基元类型又是引用类型#xff0c;在编译以及运行时#xff0c;.Net都对它做了一些优化工作。  一#xff0e;恒定的字符串要想比较全面的了解stirng类型#xff0c;首先要清楚.Net中的值类型与引用类型。在C#中#xff0…string是一种很特殊的数据类型它既是基元类型又是引用类型在编译以及运行时.Net都对它做了一些优化工作。  一恒定的字符串   要想比较全面的了解stirng类型首先要清楚.Net中的值类型与引用类型。在C#中以下数据类型为值类型     bool、byte、char、enum、sbyte以及数字类型(包括可空类型)   以下数据类型为引用类型     class、interface、delegate、object、stirng   被声明为string型变量存放于堆中是引用类型。   让我们先来看看以下三行代码有何玄机     string a str_1;     string b a;     a str_2;   在以上代码中第3行的“”有一个隐藏的秘密它的作用我们可以理解为新建而不是对变量“a”的修改。以下是IL代码可以说明这一点       .maxstack  1       .locals init ([0] string a,                [1] string b)       IL_0000:  nop       IL_0001:  ldstr      str_1       IL_0006:  stloc.0       IL_0007:  ldloc.0       IL_0008:  stloc.1       IL_0009:  ldstr      str_2         IL_000e:  stloc.0  //以上2行对应 C#代码 a str_2;       IL_0015:  ret   可以看出IL代码的第1、6行由ldstr指令创建字符串str_1并将其关联到了变量“a”中7、8行直接将堆栈顶部的值弹出并关联到变量“b”中9、10由ldstr创建字符串str_2关联在变量“a”中并没有像我们想象的那样去修改变量a的旧值而是产生了新的字符串   在C#中如果用new关键字实例化一个类对应是由IL指令newobj来完成的而创建一个字符串则由ldstr指令完成看到ldstr指令我们即可认为IL希望创建一个新的字符串 。注意是IL希望创建一个字符串而最终是否创建还要在运行时由字符串的驻留机制决定这一点下面的章节会有介绍。 所以第三行C#代码(a str_2;)的样子看起来是在修改变量a的旧值str_1但实际上是创建了一个新的字符串str_2然后将变量a的指针指向了str_2的内存地址而str_1依然在内存中没有受到任何影响所以变量b的值没有任何改变---这就是string的恒定性同学们一定要牢记这一点在.Net中string类型的对象一旦创建即不可修改包括ToUpper、SubString、Trim等操作都会在内存中产生新的字符串。   本节重点回顾由于stirng类型的恒定性让同学友们经常误解string虽属引用类型但经常表现出值的特性这是由于不了解string的恒定性造成的根本不是“值的特性”。例如     string a str_1;     a str_2;   这样会在内存中创建str_1和str_2两个字符串但只有str_2在被使用str_1不会被修改或消失这样就浪费了内存资源这也是为什么在做大量字符串操作时推荐使用StringBuilder的原因。二.Net中字符串的驻留重要  在第一节中我们讲了字符串的恒定性该特性又为我们引出了字符串的另一个重要特性字符串驻留。   从某些方面讲正是字符串的恒定性才造就了字符串的驻留机制也为字符串的线程同步工作大开方便之门同一个字符串对象可以在不同的应用程序域中被访问所以驻留的字符串是进程级的垃圾回收不能释放这些字符串对象只有进程结束这些对象才被释放。   我们用以下2行代码来说明字符串的驻留现象     string a str_1;     string b str_1;   这2行代码会在内存中产生了几个string对象你可能会认为产生2个由于声明了2个变量程序第1行会在内存中产生str_1供变量a所引用第2行会产生新的字符串str_1供变量b所引用然而真的是这样吗我们用ReferenceEquals这个方法来看一下变量a与b的内存引用地址     string a str_1;     string b str_1;     Response.Write(ReferenceEquals(a,b));   //比较a与b是否来自同一内存引用     输出True   看到了吗我们用ReferenceEquals方法比较a与b虽然我们声明了2个变量但它们竟然来自同一内存地址这说明string b str_1;根本没有在内存中产生新的字符串。   这是因为在.Net中处理字符串时有一个很重要的机制叫做字符串驻留机制。由于string是编程中用到的频率较高的一种类型CLR对相同的字符串只分配一次内存。CLR内部维护着一块特殊的数据结构我们叫它字符串池可以把它理解成是一个HashTable这个HashTable维护着程序中用到的一部分字符串HashTable的Key是字符串的值而Value则是字符串的内存地址。一般情况下程序中如果创建一个string类型的变量CLR会首先在HashTable遍历具有相同Hash Code的字符串如果找到则直接把该字符串的地址返回给相应的变量如果没有才会在内存中新建一个字符串对象。   所以这2行代码只在内存中产生了1个string对象变量b与a共享了内存中的str_1。   好了结合第一节所讲到的字符串恒定性与第二节所讲到的驻留机制来理解一下下面4行代码吧     string a str_1; //声明变量a将变量a的指针指向内存中新产生的str_1的地址     a str_2;  //CLR先会在字符串池中遍历str_2是否已存在如果没有则新建str_2并修改变量a的指针指向str_2内存地址str_1保持不变。字符串恒定     string c str_2; //CLR先会在字符串池中遍历str_2是否已存在如果存在则直接将变量c的指针指向str_2的地址。字符串驻留   那么如果是动态创建字符串呢字符串还会不会有驻留现象呢   我们分3种情况讲解动态创建字符串时驻留机制的表现   字符串常量连接     string a “str_1” “str_2”;     string b “str_1str_2”;     Response.Write(ReferenceEquals(a,b));   //比较a与b是否来自同一内存引用     输出 True   IL代码说明问题     .maxstack  1     .locals init ([0] string a,                [1] string b)     IL_0000:  nop     IL_0001:  ldstr      “str_1str_2”     IL_0006:  stloc.0     IL_0007:  ldstr      “str_1str_2”     IL_000c:  stloc.1     IL_000d:  ret   其中第1、6行对应c#代码string a “str_1” “str_2”;   第7、8对应c# string b “str_1str_2”;   可以看出字符串常量连接时程序在被编译为IL代码前,编译器已经计算出了字符串常量连接的结果ldstr指令直接处理编译器计算后的字符串值所以这种情况字符串驻留机制有效   字符串变量连接     string a “str_1”;     string b a “str_2”;     string c “str_1str_2”;     Response.Write(ReferenceEquals(b,c));     输出False   IL代码说明问题       .maxstack  2       .locals init ([0] string a,                [1] string b,                [2] string c)      IL_0000:  nop       IL_0001:  ldstr      “str_1”       IL_0006:  stloc.0       IL_0007:  ldloc.0       IL_0008:  ldstr      “str_2”       IL_000d:  call       string [mscorlib]System.String::Concat(string,                                                                   string)       IL_0012:  stloc.1       IL_0013:  ldstr      “str_1str_2”       IL_0018:  stloc.2       IL_0019:  ret   其中第1、6行对应string a “str_1”;   第7、8、9行对应string b a “str_2”;IL用的是Concat方法连接字符串   第13、18行对应string c “str_1str_2”;   可以看出字符串变量连接时IL使用Concat方法在运行时生成最终的连接结  果所以这种情况字符串驻留机制无效   3.显式实例化     string a a;     string b new string(a,1);     Response.Write(ReferenceEquals(a, b));     输出 False   IL代码       .maxstack  3       .locals init ([0] string a,                [1] string b)       IL_0000:  nop       IL_0001:  ldstr      a       IL_0006:  stloc.0       IL_0007:  ldc.i4.s   97       IL_0009:  ldc.i4.1       IL_000a:  newobj     instance void [mscorlib]System.String::.ctor              (char,                                                                     int32)       IL_000f:  stloc.1       IL_0010:  ret   这种情况比较好理解IL使用newobj来实例化一个字符串对象驻留机制无效。从string b new string(a,1);这行代码我们可以看出其实string类型实际上是由char[]实现的一个string的诞生绝不像我们想想的那样简单要由栈、堆同时配合才会有一个string的诞生。这一点在第四节会有介绍。   当然当字符串驻留机制无效时我们可以很简便的使用string.Intern方法将其手动驻留至字符串池中例如以下代码     string a a;     string b new string(a,1);         Response.Write(ReferenceEquals(a, string.Intern(b)));     输出True     程序返回Ture说明变量a与b来自同一内存地址。 三练习   代码一     string a str_1;     string b str_1;     Response.Write(a.Equals(b));     Response.Write(ReferenceEquals(a,b));     输出True (Equals比较字符串对象的值)           True (ReferenceEquals比较字符串对象的引用由于字符串驻留机制a与b的引用相同)   代码二             string a str_1str_2;             string b str_1;             string c str_2;             string d b c;             Response.Write(a.Equals(d));     Response.Write(ReferenceEquals(a, d));     输出True(Equals比较字符串对象的值)           False(ReferenceEquals比较字符串对象的引用由于变量d的值为变量连接的结果字符串驻留机制无效)   代码三     string a str_1str_2;     string b str_1 str_2;     Response.Write(a.Equals(b));     Response.Write(ReferenceEquals(a, b));     输出True(Equals比较字符串对象的值)           True (ReferenceEquals比较字符串对象的引用由于变量b的值为常量连接的结果字符串驻留机制有效。如果变量b的值由“常量变量”的方式得出则字符串驻留无效)   代码四     string a str_1;     string b String.Copy(a);     Response.Write(a.Equals(b));     Response.Write(ReferenceEquals(a, b));     输出True(Equals比较字符串对象的值)           False (ReferenceEquals比较字符串对象的引用Copy操作产生了新的string对象)   代码五     string a str_1;     string b String.Copy(a);     b String.Intern(b);     Response.Write(a.Equals(b));     Response.Write(ReferenceEquals(a, b));     输出True(Equals比较字符串对象的值)           True (ReferenceEquals比较字符串对象的引用String.Intern实现了字符串驻留)   代码六     string a str_1;     string b String.Copy(a);     string c str_1;     Response.Write((object)a (object)b);     Response.Write((object)a (object)c);     输出False (“”在两边为引用类型时则比较引用的地址所以a与b为    不同引用)           True (ReferenceEquals比较字符串对象的引用a与c由于字符串驻留机制引用相同)   代码七     string a str_1;     string c str_1;     Response.Write(a c);     输出True   刚才我们提到过“”在两边为引用类型时则比较引用的地址如果是值类型时则比较值。string为引用类型那么上面的代码是比较了变量a与c的地址还是值呢答案是比较了值因为在string类型比较的时候“”已经被重载为“Equals”了所以虽然你在用“”比较两个引用类型但实际上是在用“Equals”比较它们的值   代码八     string a a;     string b new string(a, 1);     Response.Write(a.Equals(b));     Response.Write(ReferenceEquals(a, b));     输出True (Equals比较值a与b的值相同)           False (ReferenceEquals比较字符串对象的引用)   代码九     string a a;     string b new string(a, 1);     Response.Write(a.Equals(string.Intern(b)));     Response.Write(ReferenceEquals(a, string.Intern(b)));     输出True (Equals比较值无论是否Intern都会相同)           True (ReferenceEquals比较字符串对象的引用Intern已经将b驻留至字符串池内)   代码十     string a str;     string b str_2.Substring(0,3);     Response.Write(a.Equals(b));     Response.Write(ReferenceEquals(a, b));     输出True (Equals比较值a与c的值相同)           False (ReferenceEquals比较字符串对象的引用Substring操作产生了新的字符串对象)       此段代码产生了3个string对象是哪3个呢如果你不明白还是从头再看一遍吧 四常见问题    1.“string ”与“new stirng()”的区别     string test a;     string test new string(a, 1);   以上两行代码的效果是一样的它们的区别在于加载”a”的时间不同第一行的“a”是一个常量在编译期就已经被放在一个叫做常量池的地方了常量池通常装载一些在编译期被确定下来的数据例如类、接口等等而第二行是运行时CLR在堆中生成的值为“a”的字符串对象所以后者没有字符串驻留。   2. string 与 String的区别   String的大名叫做System.String在编译为IL代码时string和System.String会生成完全相同的代码(pslong和System.Int64float和System.Single等也有此特性)   C#代码     string str_test test;            System.String Str_test test;   IL码       // 代码大小       14 (0xe)       .maxstack  1       .locals init ([0] string str_test,                [1] string Str_test)       IL_0000:  nop       IL_0001:  ldstr      test       IL_0006:  stloc.0       IL_0007:  ldstr      test       IL_000c:  stloc.1       IL_000d:  ret     所以二者的区别并不在于底层而是在于string是类似于int的基元类型System. String是框架类库FCL的基本类型二者之间有直接的对应关系。   3.StringBuilder   StringBuilder提供了高效创建字符串的方法由StringBuilder表示的字符串是可变的(非恒定的)在需要多处使用“”连接字符串变量的时候推荐使用StringBuilder来完成最后调用其ToString()方法输出。当调用了StringBuilder的ToString()方法之后StringBuilder将返回其内部维护的一个字符串字段引用如再次修改StringBuilder它将会创建一个新的字符串这时被修改的是新的字符串原来已经返回的字符串才不会发生改变。     StringBuilder有两个比较重要的内部字段大家需要掌握     m_MaxCapacityStringBuilder的最大容量它规定了最多可以放置到        m_StringValue的字符个数默认值为Int32.MaxValue。m_MaxCapacity一旦被指定就不能再更改。     m_StringValueStringBuilder维护的一个字符数组串实际上可以理解为一个字符串。StringBuilder重写的Tostring()方法返回的就是这个字段。 转载于:https://www.cnblogs.com/yidianfeng/archive/2009/02/05/1384469.html
http://www.sadfv.cn/news/90572/

相关文章:

  • 免费网站下载直播软件广州市城乡建设局
  • 徐州做网站建设上海市工程建设交易中心网站
  • h网站模版seo外包大型公司
  • 网站后台怎么上传图片wordpress 悬停遮罩
  • 做网站要买什么类型云空间网站建设费用分几年摊销
  • 邢台网站改版制作公司百度seo效果怎么样
  • 网站策划设计建设免费虚拟主机网站源码
  • html5手机网站开发视频教程外包服务平台
  • 怎么看网站的访问量螺蛳粉营销策划方案
  • 如何备案成企业网站wordpress最详细的教程视频教程
  • asp.net+h5网站开发牛商网网站做seo好么
  • 静安网站开发seo关键词是什么
  • 网站建设中 尽情期待网站开发word
  • 做的好的网站着陆页学网站开发在大学
  • 网站开发认证考试外国做家具的网站
  • 长沙市宁乡县建设局网站打开汽车之家网页版
  • asp连接数据库做登录网站完整下载为什么wordpress在ie打开很慢
  • 网站开发 案例从化哪里做网站好
  • 阿里云网站简单建设国外的服务器
  • 简述网站开发的工作流程国内 免费 云服务器
  • 做物流网站电话号码福建搜索引擎优化
  • 为什么不用原来的网站做推广创造与魔法官方网站-做自己喜欢的事
  • 公司做网站的费用怎么账务处理天心区网站建设公司
  • 哈尔滨做网站巨耀公司网站开发者兼容模式出错
  • 东莞建设年审网站网络服务商的英文缩写
  • 住房城乡建设管理网站桂林同城网站
  • 唐山免费做网站推广计划表格
  • 网站设计培训成都哪家好高要网站建设
  • 南昌网站建设模板下载网址电器网站建设目的
  • 商标注册号查询入口官网怎样进行seo