2011-08-04 19 views

答えて

10

1)はい、文字列は(一般的に)抑留されている(デフォルトによって、感謝@Eric)ため、同じ"something"の任意のインスタンスは、したがって、あなたは大丈夫だろう、同じオブジェクトを指します。 これは非常にですが、他の誰かが別のライブラリなどであなたの文字列をロックする可能性があり、デッドロックの可能性があるためです。ここを参照してください:あなたがこれを行う必要がありUsing string as a lock to do thread synchronization

private static readonly object mutex = new object(); 

lock(mutex) 
{ 
    //.... 
} 

2)はい、すべての文と同じ。あなたが持っているものは、*:

{ 
    // One line 
} 

はちょうど、

// One line 

*ほとんど何もすることが括弧を必要とcatchブロックのLukeHの例@見ることができました。

+0

文字列はデフォルトで使用できますが、デフォルトは変更できます。 –

+0

私の答えを編集しました。 –

+0

And:アセンブリに対してインターンは常に正しく動作しますか?あなたが言ったように、非常に悪い習慣です。 –

2

ジョージが書いていることはすべて正しいです。 1つの追加。とにかく、中括弧の中で実行したいものを完全にはっきりさせるために、中括弧を使うべきです。あなたは両方の線があればブロック内で実行されるというもの(いくつかの例では、ブロックを定義するためにインデントを使用しています)可能性があることを読んだとき

if(...) 
    // one line 
    // another line 

:あなたのような何かを書く事故で言ってみましょう。あなたの代わりに

if(...) 
{ 
    // one line 
} 
// another line 

を記述する場合には、もしブロック内で実行され、ものではありませんされているもの完全に透明です。

6

はい、ロックのターゲットとして文字列インスタンスを使用できます。しかし、いくつかの本当に奇妙なエッジケースがあります。

ケース1:次の例ではStringBuilderの

対リテラル 2つのロックは、同じ文字列のインスタンスを使用しません。これは、リテラルがインターンされているが、構築されたインスタンスがインターンされていないためです。

string a = "something"; 
string b = new StringBuilder().Append("some").Append("thing").ToString(); 

// These are different. 
lock (a) 
lock (b) 

ただし、手動で文字列を使用することもできます。

// These are the same. 
lock (a) 
lock (String.Intern(b)) 

ケース2:バージョン配慮

空の文字列をバージョンからのバージョンに抑留されている方法にはいくつかの違いがあります。

string a = String.Empty; 
string b = new StringBuilder().Append(String.Empty); 

// These are the same in 1.0, 1.1, 3.5, and 4.0. 
// These are different in 2.0 and 3.0. 
lock (a); 
lock (String.Intern(b)) 

ケース3:実装の違い

CLIのMicrosoftの実装はそこだけではありません。異なる実装が異なる挙動を示し、独自の警告セットを有することが考えられる。

ケース4:はアセンブリは、この飾られているかどうかに応じ

をCompilationRelaxations.NoStringInterningと(それを無視するとは対照的に)CLRが実際にそれを使用するかどうかインターン機構の動作を変更することができます。これは、同じコードが実行されたコンテキストに応じて異なる動作をする可能性があるため、特に厄介な問題です。


私が気づいていない他のエッジケースがあると確信しています。ただし、ロック目的(または参照の等価性についての暗黙の前提を必要とする目的)のために文字列インスタンスに頼ることは危険です。

+2

短い答え:文字列をロックしないでください。 – dvallejo