3

次のコードを書くと:

public void Execute()
{
    var stream = new MemoryStream();
    ...
}

次に、コード分析はこれに次のフラグを立てます。

警告1CA2000:Microsoft.Reliability:メソッド'ServiceUser.Execute()'で、オブジェクト'stream'へのすべての参照がスコープ外になる前にSystem.IDisposable.Disposeを呼び出します。C:\ Dev \ VS.NET \ DisposeTest \ DisposeTest \ ServiceUser.cs 14 DisposeTest

ただし、ファクトリパターンを作成した場合でも、オブジェクトを破棄する必要がある場合がありますが、FxCop /CodeAnalysisは文句を言いません。むしろ、それを呼び出すコードではなく、ファクトリメソッドについて文句を言います。 (ファクトリメソッドについて不満を言った例があったと思いますが、ここに投稿したものはそうではないので、それを打ち消しました)

たとえば、属性を使用して、IDisposableオブジェクトの責任をファクトリメソッドから呼び出し元に移動する方法はありますか?

このコードを取る:

public class ServiceUser
{
    public void Execute()
    {
        var stream = StreamFactory.GetStream();
        Debug.WriteLine(stream.Length);
    }
}

public static class StreamFactory
{
    public static Stream GetStream()
    {
        return new MemoryStream();
    }
}

この場合、警告はありません。FxCOP/CAに元の方法についてまだ文句を言ってもらいたいのですが。そのオブジェクトを処理するのはまだ私の責任です。

これについてFxCOP/CAに伝える方法はありますか?たとえば、私は最近、ReSharperが提供する注釈属性に挑戦し、分析エンジンの情報を伝えるために、他の方法では理解できないようにしました。

だから私はこのようなものを想像します:

public static class StreamFactory
{
    [return: CallerResponsibility]
    public static Stream GetStream()
    {
        return new MemoryStream();
    }
}

それとも、この設計はかなり離れていますか?

4

1 に答える 1

4

FxCop 10(Windows7および.NET4.0 SDKに付属)とCode Analysis 2010(Visual Studio Premium以降に付属)には違いがあります。Code Analysis 2010には、IDisposableルールの高度に改善されたバージョンを含む一連の追加ルールがあります。

VisualStudioPremiumでのCodeAnalysis2010では、ファクトリにフラグが立てられていません(ルールでは、IDisposable変数が呼び出し元のメソッドに返されることが確認されています)。ただし、ルールのコーナーケースの例外の1つが原因で、Receivingメソッドにもフラグが立てられません。ルールをトリガーするメソッド名のリストがあります。GetStreamメソッドの名前をに変更するとCreateStream、突然ルールがトリガーされます。

Warning 4   CA2000 : Microsoft.Reliability : In method 'ServiceUser.Execute()',
call System.IDisposable.Dispose on object 'stream' before all references to it are out
of scope.   BadProject\Class1.cs    14  BadProject

動作するメソッドプレフィックスのリストを見つけることができませんでした。私はいくつか試してみましたが、ルールCreate~をトリガーします。他にも、、、、など、Open~機能すると予想される多くの機能はありません。Build~Make~Get~

さらに、このルールを取り巻くバグの長いリストがあります。Visual Studio 2010でルールが変更され、誤検知が少なくなりましたが、フラグを立てるべきだった(以前のバージョンではフラグを立てていた)アイテムを見逃すことがあります。Visual Studio 2010の時間枠でルールを修正するのに十分な時間がありませんでした(バグレポートのコメントを確認してください)。

今後のRoslynコンパイラでは、コード分析でメジャーアップグレードが行われる可能性がありますが、それまではマイナーアップデートのみが予想されます。Visual Studio Dev11の現在のビルドは、必要な場所でトリガーされません。

結論として、IDisposableを戻り値として渡していることをルールがすでに検出しているため、属性はあまり役に立ちません。したがって、コード分析は、戻る前にそれを破棄するのは良くないことを知っています。文書化されていない命名規則を使用している場合、規則がトリガーされます。属性で命名規則を拡張できるかもしれませんが、実際にMicrosoftに実際の規則を修正してもらいたいと思います。

命名ガイドラインをルールのドキュメントに文書化するように要求する接続バグを作成しました。

Microsoftからのコメント:

マイクロソフトが2012年1月19日午前10時41分に投稿こんにちは。

これを調査し、ドキュメントの更新のリクエストを提出するために時間を割いていただきありがとうございます。ただし、ドキュメントチームとの話し合いの結果、要求どおりに命名規則をドキュメント化しないことにしました。

スタックオーバーフロースレッドで示したように、このルールには歴史的に多くの信頼性の問題があり、名前のキーオフは、誤検知の数を減らすために追加された内部実装の詳細でした。ただし、これは、開発者がメソッドに名前を付ける方法についての規範的なガイダンスとは見なされません。これは、一般的なコーディング手法の調査後に追加されました。長期的な修正は、ルールの信頼性を向上させることであり、ルールが改善されるにつれて変更され続ける内部実装の詳細に基づいて、公開ドキュメントに命名ガイダンスを追加することではないと考えています。

よろしくお願いいたします。VisualStudioコード分析チーム

于 2011-12-14T20:18:29.703 に答える