2017-03-21 5 views
2

現在のコンテキストでは、開始と停止の2つのメソッドがあります。これらの2つのメソッドは、関数から順番に呼び出されます。ある人が自分のメソッド内でStart()を呼び出すが、Stop()を呼び出すことは忘れてしまう可能性があります。例えばこの文脈においてC#のメソッド実装に関するコンパイル時にカスタム警告を表示する

private void A() 
{ 
    Start(); 

    //Buisness logic goes here 

} 

コードは、警告またはエラーをコンパイル時にすべての開始の())に対応するストップ(が存在すべきである旨が表示される必要があります。誰かがC#で同じものを実装する方法についてのアイディアを提案できますか?

実装の適切な方法が

private void A() 
{ 
    Start(); 

    //Buisness logic goes here 

    Stop(); 

} 
+4

あなただけの代わりに、テンプレートメソッドパターンを実装する必要がありますように聞こえます。あるいは 'Start()'を 'Execute(Action)'に変更します。 –

+2

このクラスは 'IDisposable'を実装し、' Dispose'では 'Stop'を呼び出します(あるいは' Start'はクラス自体ではなく 'IDisposable'を返します)。スコープ内に配置されていない「IDisposable」のチェックが異なります。 – Evk

+0

スタートとストップを連続して呼び出す方法はありませんが、異なる方法から呼び出すことはできませんか? – Evk

答えて

1

だろうEVKは、ここでは、良いヒントを与えた私は、より詳細にそれを行うだろうかです:

  1. が実装(例えばStartStop)のクラスを持っていますIDisposable

    public class StartStop : IDisposable 
    { 
        public StartStop() { Start(); } 
    
        public void Dispose() { Stop(); } 
    
        protected void Start() { /*...*/ } 
    
        protected void Stop() { /*...*/ } 
    } 
    
  2. で、このクラスをご利用ください:

    private void A() 
    { 
        using(var startStopCaller = new StartStopCaller()) 
        { 
         // Your code here 
        } 
    } 
    

usingDispose()を確認しますと、その後Stop()はハードクラッシュを除いて呼び出されます。

+1

プログラマーが 'var startStop = new StartStop()'を 'using'の中に置かずに止めることは何一つありません。あなたは元の問題に戻ります! – Jamiec

+1

@Jamiec一般的には真実ですが、多くのコード検査ツールはそのことについて警告を出します。 – Evk

+0

@ Jamiec私は同意しますが、プログラマがリフレクションを使用してプライベートメソッドを呼び出すのを止めるものはありませんので、常に安全対策を迂回する方法があるでしょう。 – Sentry

0

これは、2つの主要な方向で、多くの方法でアプローチすることができます:あなたは.NETプラットフォームのそれ以降のバージョン、およびので、ロザリンコンパイラ(Defaults from VS2015 and onwards)を使用している場合は、あなたがに見ることができます

  • これをチェックするコンパイラプラグインを作成します。ここではいくつかのリソースは次のとおりです。
  • コメントの一部が指摘しているように、これはコードとプログラムデザインで修正される可能性があります。 これはおそらくこれにアプローチする "正しい"方法です。いくつかの例:
    • implementing IDisposableを検討し、using statementであなたのクラスを使用するには - しかし、停止し、オブジェクトを廃棄することはここでは同じではないかもしれないことを覚えておいてください。あなたは、あなたのプログラムの内部の仕組みについての知識を持って、これに関する情報に基づいた意思決定を行うべきです。
    • これらのクラスを他の場所から呼び出す場合は、StartStopの両方のメソッドを含むインターフェイスを実装できるようにすることができます。そして、呼び出し側のクラスが単にこのインタフェースとして扱うようにし、どちらの実装を使用していても両方のメソッドを呼び出すようにします。
    • Start()とStop()を順番に実行しないようにコードを再設計します。これには、プログラムの基本的な設計変更とそれがどのように機能するかが必要になるかもしれませんが、価値があるかもしれません。読みやすさと保守性の両方を考慮しています。
+0

私たちはまた、2012年のvsを使用している消費者があります。また、この特定のコンテキストで私たちはどのように行くのか分かりません。 – Prasad

+0

その後、コンパイラのプラグインの部分をスキップして、コードワイズの再設計を行ってください。 VSバージョンに関係なく動作します。 –

2

私はあなたがプログラマにそれをさらすことなくStartStopの世話をするためにあなたのパターンを変更することをお勧め。

ではなく Executeメソッドを実装するに Start & Stopを実装するクラスを変更し、 Start & Stopを公開してもいけない

public class MyClass 
{ 
    private void Start(){} // old public method 
    private void Stop(){} // old public method 

    public void Execute(Action action) 
    { 
     Start(); 
     action(); 
     Stop(); 
    } 
} 

使用法:

var impl = new MyClass(); 
impl.Execute(() => { 
    // do something in between start & stop 
}); 
+0

これは、消費者のコードの変更量が必要です。それは受動的な変化でなければなりません。 – Prasad

+0

私はOPからの要件ではないことを知っていますが、アクションが例外をスローすると、 'Stop()'は呼び出されません。しかし私は、これが私の「使用する」解決策よりも悪意を持って回避することは難しいことに同意します。 – Sentry

+1

@Sentry良い点 - 'try..finally'を使って修正するのに十分簡単です。 – Jamiec

関連する問題