国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
?。。。# 字符串詳解?。。。?!

【主要內(nèi)容】

關(guān)于C#的String。
C# String 和 string 有何區(qū)別
字符串的不變性
字符串比較 == 和 Equals(string str1, string str2)
字符串駐留

【概念闡述】
====================
@ C# String 和 string 有何區(qū)別
====================
1、string是c#中的關(guān)鍵字,String是.net Framework的類;
2、c# string映射為.net Framework的String,如果用string,編譯器會(huì)把它編譯成String,所以如果直接用String就可以讓編譯器少做一點(diǎn)點(diǎn)工作;
3、string始終代表System.String,String只有在前面有using System的時(shí)候并且當(dāng)前命名空間中沒有名為String的類型(class、struct、delegate、enum)
     的時(shí)候才代表System.String

====================
@字符串的不變性
====================
1、一個(gè)字符串一旦被創(chuàng)建完成后,將不能再做任何改變,比如改變、增加或減少一個(gè)字符。
2、當(dāng)把一個(gè)字符串變量賦給另一個(gè)字符串變量時(shí),會(huì)得到內(nèi)存中同一個(gè)字符串的兩個(gè)引用,但與引用類型在常見的操作上又有區(qū)別。當(dāng)你修改其中一個(gè)字符串的時(shí)候,
     會(huì)創(chuàng)建一個(gè)全新的String對(duì)象,其引用的原字符串并不會(huì)改變,因而另一個(gè)字符串變量的值不變。
3、當(dāng)我們創(chuàng)建了字符串對(duì)象a,它的值是“1234”,當(dāng)我們?cè)賱?chuàng)建一個(gè)值為“1234”的字符串對(duì)象b時(shí)它不會(huì)再去分配一塊內(nèi)存空間,而是直接指向了a在內(nèi)存中的地址。

=================================
@字符串比較 == 和 Equals(string str1, string str2)
=================================
==是Equals(string,string)的一個(gè)重載,兩者內(nèi)部機(jī)制完全一樣。如果兩字符串引用相同直接返回true,若不同則先比較引用再比較字符串的值。
【實(shí)驗(yàn)步驟】
=========================
@不可使用new操作符來創(chuàng)建字符串對(duì)象
=========================

public static bool operator ==(string a, string b){
      
return string.Equals(a, b);
}

public static bool Equals(string a, string b){
      
if ((object)a == (object)b){  // 先比較引用是否相同,若相同直接返回True。
            return true;
       }
      
if ((a != null) && (b != null)) { // 引用不同的再比較值是否相同。
            return a.Equals(b);
      }
     
return false;
}

public class CreateString{
public static void Main(string[] args){
  
string str = new string("a string");
}
}

編譯錯(cuò)誤提示:
error CS1502: 與“string.String(char*)”最匹配的重載方法具有一些無效參數(shù)
error CS1503: 參數(shù)“1”: 無法從“string”轉(zhuǎn)換為“char*”

事實(shí)上 string 類并未提供 string(string) 構(gòu)造函數(shù)。

==================
@字符串連接測(cè)試(不變性)
==================

字符串連接
using System;

public class StringTest{
public static void Main(string[] args){
  
// String 為引用類型,但卻有一些值類型的表現(xiàn)。
  string s1 = "a string";
  
string s2 = s1;     // s1 和 s2 都引用 "a string"。
   Console.WriteLine("s1 is " + s1);
   Console.WriteLine(
"s2 is " + s2);

   s1
= "another string";   // 修改 s1。
   Console.WriteLine("s1 now is " + s1);
   Console.WriteLine(
"s2 now is " + s2);  // s2 的值仍為 "a string"。
  
   Console.ReadLine();
}
}

輸出:
s1 is a string
s2 is a string
s1 now is another string
s2 now is a string

=============
@ 字符串存儲(chǔ)
=============
1、相同字符串在內(nèi)存中只保存一份。

using System;
class Test{
        
static void Main(string[] args){
            
string a = "1";
            
string b = "1";
            
string c = "2";
         }
     }
}

使用visual studio 2005中的調(diào)試,轉(zhuǎn)到反匯編,可以得到下面內(nèi)容:
......
            string a = "1";
0000002b mov         eax,dword ptr ds:[022C3048h] // 與下面相同
00000031 mov         ebx,eax
            string b = "1";
00000033 mov         eax,dword ptr ds:[022C3048h] // 與上面相同
00000039 mov         esi,eax
            string c = "2";
0000003b mov         eax,dword ptr ds:[022C307Ch] // 不同
......

2、相同字符串GetHashCode()返回相同值。

using System;
public class Test{
public static void Main(string[] args){
  
string a = "0";
  
string b = "0";
  
string c = "1";
   Console.WriteLine(a.GetHashCode());
   Console.WriteLine(b.GetHashCode());
   Console.WriteLine(c.GetHashCode());
}
}

輸出:
-842352752
-842352752
-842352753

3、字符串駐留

using System;
public class Test{
public static void Main(string[] args){
   String s
= “Hello”;
   Console.WriteLine(Object.ReferenceEquals(“Hello“,s));
}
}

輸出:
True

說明:當(dāng) CLR 初始化時(shí),它會(huì)創(chuàng)建一個(gè)內(nèi)部的散列表,其中鍵位字符串,值為指向托管堆中字符串對(duì)象的引用,初始化為空。當(dāng)JIT編譯器編譯方法時(shí),
它會(huì)在散列表中查找每一個(gè)常量字符串,并添加到散列表中,值相同的字符串不重復(fù)添加。對(duì)于上面的代碼,編譯器會(huì)對(duì)查找到的第一個(gè)"Hello"字符串,
將現(xiàn)在托管堆中構(gòu)造一個(gè)新的 String 對(duì)象(指向在字符串),然后將 "Hello" 字符串和指向該對(duì)象的引用添加到散列表中。由于散列表中已經(jīng)存在 "Hello"
字符串,對(duì)于查找到的第二個(gè) "Hello" 字符串,將不執(zhí)行任何操作。
    代碼執(zhí)行時(shí),它會(huì)在第一行發(fā)現(xiàn)一個(gè) "Hello" 字符串引用,于是便在內(nèi)部散列表中查找 "Hello",找到后將先前創(chuàng)建的 String 對(duì)象的引用保存到變量 s 中。
當(dāng)執(zhí)行第二行代碼時(shí),CLR 會(huì)再一次在內(nèi)部散列表中查找 "Hello",并把對(duì)應(yīng)的 String 對(duì)象的引用傳遞給 Object 的靜態(tài)方法 ReferenceEquals 作為參數(shù)。
    通過上面的分析,顯然結(jié)果為 True。當(dāng)一個(gè)引用字符串的方法被 JIT 編譯時(shí),所有嵌入在源代碼中的常量字符串總會(huì)被添加到 CLR 內(nèi)部的散列表中,
但是,運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的字符串卻不會(huì),參看下面的代碼:

using System;
public class Test{
public static void Main(string[] args){
  
string s1 = "Hello";
  
string s2 = "Hel";
  
string s3 = s2 + "lo";

   Console.WriteLine(Object.ReferenceEquals(s1,s3));  
}
}

輸出:
False

說明:在上面的代碼中,s2 引用的字符串 "Hel" 和一個(gè)文本常量字符串 "lo" 連接構(gòu)造一個(gè)新的位于托管堆中的字符串對(duì)象,該引用保存在 s3 中,但并未添加到散列表中,
與散列表中的 "Hello" 在托管堆中各有一份存儲(chǔ),因此返回的結(jié)果是 False。需要注意的是,如果 s3 連接的是兩個(gè)字符串常量 "Hel" + "lo",則又將返回 True。這是因?yàn)?br>C# 編譯器在將代碼編譯成 IL 指令時(shí)會(huì)將兩者連接。

============
@字符串比較
============

using System;
public class Test{
public static void Main(string[] args){
  
string s1 = "Hello";
  
string s2 = "Hel";
  
string s3 = s2 + "lo";

   Console.WriteLine(Object.ReferenceEquals(s1,s3));
   Console.WriteLine(Equals(s1,s3));
   Console.WriteLine(s1
== s3);
}
}

輸出:
True
True

說明:參看概念闡述中對(duì)字符串比較內(nèi)部實(shí)現(xiàn)的說明。雖然 s1 和 s3 引用不同,但String 的Equals(string,string) 方法還會(huì)對(duì)字符串的值進(jìn)行比較,因?yàn)橹迪嗤苑祷亟Y(jié)果為 True。顯然用Equals(string,string)/== 效率上要比僅比較引用的 ReferenceEquals(string,string)差很多,如果應(yīng)用程序中所有的字符串比較都僅比較引用,性能將會(huì)大大提升,String 類提供的兩個(gè)靜態(tài)方法允許我們做到這一點(diǎn)。

public class Test{
public static void Main(string[] args){
  
string s1 = "Hello";
  
string s2 = "Hel";
  
string s3 = s2 + "lo";

   s3
= String.Intern(s3);

   Console.WriteLine(Object.ReferenceEquals(s1,s3));
   Console.WriteLine(Equals(s1,s3));
   Console.WriteLine(s1
== s3);
}
}

輸出:
True
True
True

說明:方法 Inter(string) 在 CLR 內(nèi)部散列表中查找參數(shù)指定的字符串,如果能找到返回其引用,如果未找到,字符串將被添加到散列表中,并返回引其引用。
如果 String 對(duì)象不再被進(jìn)程中的所有應(yīng)用程序域所引用(作為參數(shù)傳遞給 Intern 方法的那個(gè) String 對(duì)象),垃圾收集器可以收回其所占內(nèi)存及在三列表中的記錄。
一個(gè)字符串對(duì)象可以被同一個(gè)進(jìn)程中的多個(gè)應(yīng)用程序域訪問,即字符串的駐留是以進(jìn)程為單位的。參看下面的代碼:

using System;
public class CreateString{
public static void Main(string[] args){
  
string s1 = "Hello";
  
string s2 = s1;
  
string s3 = s1 + " joe";

  
//MyIntern();

   Console.WriteLine(String.IsInterned(s1)
!= null);
   Console.WriteLine(String.IsInterned(s2)
!= null);
   Console.WriteLine(String.IsInterned(s3)
!= null);
}

public static void MyIntern(){  
   String.Intern(
"Hello joe");
}
}

輸出:
True
True
False

如果將注釋部分加入到代碼中則輸出:
True
True
True

【參考資源】
《你真的了解.net中的String嗎》 http://terrylee.cnblogs.com/archive/2005/12/26/304876.aspx
《進(jìn)一步了解 String》   http://lixianhuei.cnblogs.com/archive/2005/12/27/305445.html
《Microsoft.NET框架程序設(shè)計(jì)》

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
你真的徹底了解值類型/引用類型,裝箱/拆箱,Object類嗎?
C# 字符串(String) | 菜鳥教程
C# 遞歸算法?。╪多舉例)
?? 學(xué)會(huì)編程入門必備 C# 最基礎(chǔ)知識(shí)介紹(四)——數(shù)組、字符串、結(jié)構(gòu)體、枚舉、類
淺析C#中的“==”和Equals
C#入門代碼 - C Programmer's Cookbook - C 博客
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服