日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
你真的理解正確String某些特性了嗎?

最近在園子里看到幾篇關(guān)于string的文章,感覺其中有一些誤解,不知道是自己理解有誤還是園友理解錯(cuò)誤,也沒發(fā)現(xiàn)有園友提出質(zhì)疑,索性也將自己的一點(diǎn)理解寫出來,也對(duì)一些質(zhì)疑提出了自己的解釋,不管怎樣我希望如果是我哪里理解錯(cuò)誤大家一定要提出來,我們一起進(jìn)步,否則真的會(huì)誤導(dǎo)很多人,也感覺到寫文章是要負(fù)責(zé)任的,否則就干脆寫日志,不要發(fā)表出來誤導(dǎo)到了一些對(duì).Net不熟悉的朋友!

創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括上饒網(wǎng)站建設(shè)、上饒網(wǎng)站制作、上饒網(wǎng)頁制作以及上饒網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,上饒網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到上饒省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

1.在DoNet中String是不可改變的,什么叫不可變呢,首先大家先看下面的例子:

string a = "1";
Console.WriteLine(a);//1    
a+="2";
Console.WriteLine(a);//12
大家可以看看下面生成的對(duì)應(yīng)的IL代碼,可以看到a+="2"并非是在原有分配的堆中進(jìn)行修改,
而是創(chuàng)建了一個(gè)新的字符串;
而+在IL中也是使用Concat,將兩個(gè)字符串聯(lián);
所以String的不可變就是當(dāng)你在創(chuàng)建了字符串后其不可修改;
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代碼大小       34 (0x22)
  .maxstack  2
  .locals init ([0] string a)
  IL_0000:  nop
  IL_0001:  ldstr      "1"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000d:  nop
  IL_000e:  ldloc.0
  IL_000f:  ldstr      "2"
  IL_0014:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_0019:  stloc.0
  IL_001a:  ldloc.0
  IL_001b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0020:  nop
  IL_0021:  ret
} // end of method Program::Main

2.當(dāng)創(chuàng)建多個(gè)字符串內(nèi)容相同的對(duì)象時(shí),都只會(huì)指向同一個(gè)引用;

            string a = "11";
            string b = "11";
            string c = "11";
            string d = "1";
            d += "1";

a和b都指向同一個(gè)a的引用,并不會(huì)為b重新分配內(nèi)存;這樣即可保證內(nèi)存有效利用;這一點(diǎn)用IL不是很好看出來,所以大家可以按下面方法去比較他們的引用地址,都是指向同一個(gè)堆;

Console.WriteLine(string.ReferenceEquals(a, b));
Console.WriteLine(string.ReferenceEquals(a, c));
Console.WriteLine(string.ReferenceEquals(c, b));
Console.WriteLine(string.ReferenceEquals(a, d));
Console.WriteLine(string.ReferenceEquals(b, d));
Console.WriteLine(string.ReferenceEquals(c, d));

運(yùn)行結(jié)果:

   True
   True
   True
   False
   False
   False

這說明當(dāng)我們新建一個(gè)字符串以后,將為其分配內(nèi)存,而之后如何有值和其相同的字符串不會(huì)被創(chuàng)建分配堆而是直接分配其引用;

3.字符串比較:

==和!=是為了比較String對(duì)象的值是否相同而不是比較引用;

例如等號(hào)首先是比較引用是否相同,因?yàn)橐孟嗤狄欢〞?huì)相同,就避免了再去對(duì)值進(jìn)行比較;

而引用如果不同再去比較值,相同則返回true;

總之==一定一定是為了比較字符串的值是否相同;

string s2 = new StringBuilder().Append("My").Append("Test").ToString();
string s3 = new StringBuilder().Append("My").Append("Test").ToString();
Console.WriteLine((object)s2==(object)s3);//False

上面是返回False,大家肯定有些迷惑,而此前一位園友則解釋我也不盡贊同,這里只發(fā)表我的解釋:

此處比較的是兩個(gè)引用類型,為什么這么說,因?yàn)榇蠹叶贾酪玫刂范际谴娣旁跅V?而此處正是將存放在棧中的引用地址裝箱轉(zhuǎn)換成了引用類型也就是分別創(chuàng)建了兩個(gè)值為引用地址的堆,而他們引用地址的值肯定不一樣,所以結(jié)果顯然就是False了;

4.為什么總是提倡使用StringBuilder對(duì)象;

如果用String,每進(jìn)行一次字符串的拼接就要分配一個(gè)新的堆,如果只有一兩次倒無所謂,如果頻繁如此操作性能會(huì)很差;但StringBuilder是在為其分配的堆上做修改,不會(huì)重新分配,所以性能比String拼接字符串好;相信大家理解上面幾點(diǎn)了我這里也純粹是廢話了,呵呵!

5.***就是看到有人提到Intern方法,我感覺他們對(duì)此方法具體功能理解不透徹存在誤解;
首先看下面例子:

        static void Main(string[] args)
        {
            string a = "12";
            string b = "1";
            b += "2";
            string c = string.Intern(b);
            Console.WriteLine((object)a == (object)b);//false
            Console.WriteLine((object)a == (object)c);//true
            Console.WriteLine((object)b == (object)c);//false
        }
       
  static void Main(string[] args)
        {
            string a = "1212";
            string b = "1";
            b += "2";
            string c = string.Intern(b);
            Console.WriteLine((object)a == (object)b);//false
            Console.WriteLine((object)a == (object)c);//false
            Console.WriteLine((object)b == (object)c);//true
        }
       
  static void Main(string[] args)
        {
            string b = "1";
            b += "2";
            string c = string.Intern("12");
            Console.WriteLine((object)b == (object)c);//false
        }

先看***個(gè)Main,我根據(jù)***個(gè)Main來解釋:

如果傳遞給Intern的是一個(gè)變量的引用地址,那么他會(huì)檢索是否用與此引用地址所指向的堆的值相同的其他堆,如果有他會(huì)返回此堆的引用地址,也就是a。

我們再來看第二個(gè)Main來繼續(xù)解釋:

如果沒有找到與所指向的堆的值相同的其他堆,他將返回b的引用地址;

***看第三個(gè)Main做***解釋:

如果傳遞進(jìn)去的是字符串而不是引用地址,他一樣會(huì)檢索是否存在與此字符串相同的堆,如果有則返回此堆的引用地址,如無則駐留此字符串并返回其引用地址;

而這里所將的駐留也是String的特殊之處,字符串在被創(chuàng)建后不會(huì)被立即回收,即使已不存在對(duì)其引用;他會(huì)在被創(chuàng)建之后一直駐留在內(nèi)存中直至程序結(jié)束,大家可以查看MSDN解釋,下面將拿出一些MSDN的解釋來配合說明一下;

其中=>符號(hào)的是我做的注釋:
------MSDN解釋--Start------------------------------------------------------------------------------------
在1.1中
string str1 = String.Empty;
string str2 = String.Intern(String.Empty);
if ((object) str1) == ((object) str2);
...
==>是返回false,但在2.0中返回true,所以更加證實(shí)了如上所說;下面主要是講解了String的拘留池概念,大家理解上面概念后相信理解他也不成問題;

公共語言運(yùn)行庫通過維護(hù)一個(gè)表來存放字符串,該表稱為拘留池,它包含程序中以編程方式聲明或創(chuàng)建的每個(gè)唯一的字符串的一個(gè)引用.因此,具有特定值的字符串的實(shí)例在系統(tǒng)中只有一個(gè).例如,如果將同一字符串分配給幾個(gè)變量,運(yùn)行庫就會(huì)從拘留池中檢索對(duì)該字符串的相同引用,并將它分配給各個(gè)變量.Intern 方法使用拘留池來搜索與 str 值相等的字符串.如果存在這樣的字符串,則返回拘留池中它的引用。

如果不存在,則向拘留池添加對(duì) str 的引用,然后返回該引用.如果要減少應(yīng)用程序分配的內(nèi)存總量,請(qǐng)記住留用字符串有兩個(gè)不希望出現(xiàn)的副作用:首先,為留用的 String 對(duì)象分配的內(nèi)存在公共語言運(yùn)行庫 (CLR) 終止之前不大可能釋放.這是因?yàn)?CLR 對(duì)留用的 String 對(duì)象的引用可能保持到應(yīng)用程序終止之后,甚至可能保持到應(yīng)用程序域終止之后.其次,要留用字符串,必須先創(chuàng)建字符串.即使 String 對(duì)象使用的內(nèi)存最終將通過垃圾回收,仍然必須分配該內(nèi)存.

上面就說到了[為留用的 String 對(duì)象分配的內(nèi)存在公共語言運(yùn)行庫 (CLR) 終止之前不大可能釋放.]

.NET Framework 2.0 版引入了 CompilationRelaxations.NoStringInterning 枚舉成員.

NoStringInterning 成員將程序集標(biāo)記為不需要字符串拘留.可以使用 CompilationRelaxationsAttribute 屬性將NoStringInterning 應(yīng)用于某個(gè)程序集.使用本機(jī)映像生成器 (Ngen.exe) 將該程序集安裝到本地計(jì)算機(jī)上的本機(jī)映像緩存時(shí),不使用字符串拘留.這里所提到的本機(jī)映像可以改善內(nèi)存使用情況,大家可以查MSDN詳細(xì)了解;

【編輯推薦】

  1. 詳解Java String字符串對(duì)象的創(chuàng)建及管理
  2. String對(duì)象的理解進(jìn)行時(shí)
  3. 在.NET程序中正確使用String類型

網(wǎng)頁名稱:你真的理解正確String某些特性了嗎?
分享地址:http://www.dlmjj.cn/article/dpschjp.html