2011-06-21 105 views
9

String類中有一個方法IsInterned()。我從來沒有使用這種方法。請幫我理解這種方法的最佳用途。String.IsInterned的目的是什麼?

+2

不滿意官方文檔在MSFT? http://msdn.microsoft.com/en-us/library/system.string.isinterned.aspx – tzup

+5

@tzup:文檔說什麼功能,而不是當你使用它。 – Gabe

回答

3

一種可能的用法是如果你想鎖定字符串值。

在下面:

string s = //get it from somewhere, e.g. a web request 
lock (s){ 
//do something 
} 

有一個問題,因爲有可能是同一個字符串兩個不同的要求,但他們都進入受保護的代碼。這是因爲可能有兩個不同的字符串對象具有相同的值。

但是有一些名爲實習生池,這是一個表,其中包含一些字符串的單個實例(例如所有的文字)。

你可以用它來作鎖定工作:

string s = //get it from somewhere, e.g. a web request 
lock (string.Intern(s)){ 
//do something 
} 

此功能將參考返回到實習生池,它具有相同的值是個字符串,因此是安全的鎖定。

IsIntern函數只是檢查您所持有的引用是否是對intern池中的字符串的引用。

+6

切勿鎖定在字符串上。字符串是域敏捷的,即可以從多個應用程序域訪問相同的字符串實例,特別是在實施時。結果將是一個線程可能正在等待一個鎖被釋放到一個無關的appdomain中......非常討厭的效果。 – MaLio

+0

鎖定在string.Intern將結合鎖! – usr

1

C#中的字符串字面值被實現(即它們被存儲到一個實習池中),所以 對於每次出現的字面量只有一個實例。如果您正在製作自己的 語言(例如某些腳本系統),則可以使用IsInterned和Intern來產生 相同的內容。

2

參考的Eric後,我認爲這是在那裏實習解釋

+3

字符串「IsInterned」不會出現在該文章中。 – usr

0

看一看this最好的。該線程中實際上有一個用例。

7

考慮到實習是一種優化;它增加了其他一些可取的品質。特別是interning具有以下好品質:

  1. 內存不浪費在重複的字符串上。
  2. 已知要被攔截的字符串之間的平等比較是非常快的。
  3. 恰好被實施的字符串之間的平等比較仍然比沒有被實施時快得多。
  4. 其他比較在某些情況下可以獲得性能優勢。

它具有以下壞的品質:

  1. 字符串不是垃圾收集經常(如果有的話),使內存可以回收上從來沒有出現過,或字符串使用很長一段時間。 (實習生所有的字符串,你可能最終會使用非常討厭的內存)。

作爲一種優化,我們使用它來衡量好質量是否超出了壞質量或壞質量不成立的地方(如果我們知道字符串將在應用程序的整個生命週期中運行無論如何,或者知道它會被多次使用,那麼不好的部分就不成立)。

出於同樣的原因,我們不使用它的壞質量會超出好處。 (大多數時候)。

IsInterned()可以用來找到一箇中途點。

考慮我有一個字符串屬性Name

public string Name { get; set; } 

比方說,我知道這是共同尋找對象與給定Name,或試圖找到對象具有相同Name或以其他方式做了很多對其進行平等比較。或者讓我們說我知道會有很多其他對象具有相同的Name。或兩者。

在這種情況下,我可能會考慮實習:

private string _name; 
public string Name 
{ 
    get { return _name; } 
    set { _name = string.Intern(value); } 
} 

當然,這是否是一個好主意或不取決於上面提到實習的好和壞的品質。

在兩者之間使用和不使用的可能性:

private string _name; 
public string Name 
{ 
    get { return _name; } 
    set { _name = string.IsInterned(value) ?? value; } 
} 

這裏如果字符串value已經拘禁那麼我們實習的下雙方都已經開始工作,我們沒有受到任何更多,所以我們利用它。但是,如果value尚未實施,那麼我們只是按原樣使用它。

這也是一種優化,針對不同情況進行優化。只有在合理數量的值被其他代碼(或者因爲它們與程序集中的文字相匹配)相關時,它纔會有用,否則它只會浪費時間進行查找。它可能不如Intern()那麼有用,而不是僅僅使用字符串而忽略實習,但這確實表明它可能有用。