2012-03-16 12 views
3

私は理解しようとしている奇妙な状況に陥っています。CA2000は「使用する」方法を使用していますが、try/finallyを使用していません

var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml)); 
using(ms) 
{ 
    var x = XamlReader.Load(ms); 
    _defaultControlTemplate = x as ControlTemplate; 
} 

しかし、この他の作品ではありません:Microsoft's documentation 1として

var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml)); 
try 
{ 
    var x = XamlReader.Load(ms); 
    _defaultControlTemplate = x as ControlTemplate; 
} 
finally { ms.Dispose(); } 

のコードのこの作品は、CA2000 (...すべての参照前にオブジェクト上のDisposeを呼び出す)に与えています

usingステートメントを使用すると、オブジェクトのメソッドを呼び出すときに例外が発生した場合でもDisposeが確実に呼び出されます。 tryブロック内にオブジェクトを配置し、finallyブロックでDisposeを呼び出すことで同じ結果を得ることができます;実際には、これはusingステートメントがコンパイラによってどのように翻訳されるかです。

私は本当にここで失われています...同じものと思われる2つのステートメントはありませんか?

更新

人々が主張するのでusing ettiqueteを説明する上で(私のコメントを読まず)。私はこのようにそれを置くでしょう:

using (var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml))) 
    { 
    var x = XamlReader.Load(ms); 
    _defaultControlTemplate = x as ControlTemplate; 
    } 

このはまだ FxCopの上CA2000を与えるので、オリジナルの疑問は残ります。あなたはこれは、Visual Studio 2010と全体の機能で見ることができるようにいくつかのスクリーンショットを追加

アップデート2

最初のバージョン(警告を与える): With warning

セカンドバージョン(OK): Correct build

+0

もちろん、IDisposableを 'using'括弧内にインスタンス化することをお勧めします。 – Jcl

+0

@ xanatos:これは私の考えでもありましたが、C#言語の仕様をチェックして、オブジェクトが 'try'ブロックの外に作成されたことを示しています。 –

+0

コード分析(別名FxCOP 11)のVS2010に問題があるとフラグが立てられていない、このシナリオに関して古いFxCOPバージョンにバグがありますか? –

答えて

4

ThreadAbortExceptionについての質問もいくつか間違ったものには適用されませんでしたいくつかのものを削除しました。)

おそらくCA2000によって報告された偽陽性を経験しています。 Microsoft Connect for CA2000を検索することができます。かなりの数の問題が存在します(すべてが偽陽性のバグではありません)。

私は個人的に、これらの偽陽性のためにいくつかのプロジェクトでCA2000をオフにしました。私はCode AnalysisでVisual Studio 2010を使用しています。CA2000をあまりにも頻繁に抑制しなければならないので、私が今作業中のプロジェクトでそれを無効にすることにしました。

+1

ですが、 "使用する"はあなたが全く言及していない問題を解決しません。 using "は魔法ではなく、ThreadAbortExceptionが発生したと仮定します*リソースが割り当てられ、* before *変数msに値を保持するオブジェクトへの参照が割り当てられている場合* ?変数は初期化されておらず、デフォルトのNULL値を持っているので、finallyブロックはそれを破棄することができません。 "使用"は*礼儀正しさ*であり、 –

+0

@EricLippert Fxcopは、Microsoftの文書(私がリンクしている)が両方のステートメントがコンパイラによって同じ出力を生成すると言うなら、コード出力を解析することになっています。コード分​​析の警告を発する理由とそれを発行しない理由:-( – Jcl

+0

@MartinLiversage [Microsoft Connectのこの問題](http://connect.microsoft.com/VisualStudio/feedback/details/4698) 15/code-analysis-warning-ca2000-using-c-construct#詳細)は私がここにいる問題のように聞こえる。私はupvoteに今すぐ接続するためにログインすることができません...私は当分の間それを残して、ちょうどtry/finallyを使用します(私は反対していません...私はちょうど試していたそれが起こった理由を理解する)。ありがとう、Microsoft Connectへのリンクは役に立ちました – Jcl

-1

正しいコードは、あなたが使用して内部で宣言し、割り当てる必要が

using(var ms= new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml))) 
{ 
    var x = XamlReader.Load(ms); 
    _defaultControlTemplate = x as ControlTemplate; 
} 

だろうステートメント。参考問題に

を明確に私はあなたが以下のんと仮定します:

var ms; 
using(ms= new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml))) 
{ 
    var x = XamlReader.Load(ms); 
    _defaultControlTemplate = x as ControlTemplate; 
} 

それが配置された後、あなたはまだMS変数を使用することができますし、それが適切に

編集を処分呼び出します。 。それがメッセージの内容です。あるいは、使用ブロック内の別のvarにmsを割り当てます。

+0

私は質問にコメントとして、読みやすくするためにそれを付け加えました。同じことが起きる、fxcopのCA2000(元の質問です)。オブジェクトはいずれの方法でも正しく配置されますが、私はfxcopでその警告を受け取るのが嫌いです。 – Jcl

+1

'var ms;'は完全に不正なコードです。 – jason

+0

これで言及しました....そうです、それは –

0

2つのコードに違いがあり、FxCOPにフラグを立てる理由があるかもしれません。

Visual Studio 2010 Premiumのコード解析では、どちらのコードにも警告が表示されないため、古いFxCOPバージョンと比較していくつかの理解が追加されている可能性があります。

とにかく、違いは、実際には、使用ブロックが質問に表示されているtry/catchブロックに変換されないということです。

は、ここでより良い翻訳です:

var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml)); 
var temp = (IDisposable)ms; 
try 
{ 
    var x = XamlReader.Load(ms); 
    _defaultControlTemplate = x as ControlTemplate; 
} 
finally 
{ 
    if (temp != null) 
     temp.Dispose(); 
} 

(注)このあなたの警告の理由で、私はを言っていないよ、私はちょうどそれは、コードの2枚の間に1つの違いだと言っています。

関連する問題