Resharperは、静的にできるasp.netページごとに複数の関数を指摘することを好みます。それらを静的にすると、役に立ちますか?それらを静的にしてユーティリティクラスに移動する必要がありますか?
Resharperは、静的にできるasp.netページごとに複数の関数を指摘することを好みます。それらを静的にすると、役に立ちますか?それらを静的にしてユーティリティクラスに移動する必要がありますか?
回答:
静的メソッドとインスタンスメソッド
10.2.5 C#言語仕様の静的メンバーとインスタンスメンバーが違いを説明しています。一般に、静的メソッドはインスタンスメソッドに比べてパフォーマンスを非常にわずかに向上させますが、やや極端な状況でのみ可能です(詳細についてはこの回答を参照してください)。
FxCopまたはコード分析のルールCA1822は次のように述べています。
「[メンバーを静的としてマーク]した後、コンパイラーはこれらのメンバーに非仮想呼び出しサイトを発行します。これにより、各呼び出しの実行時に、現在のオブジェクトポインターがnullでないことを確認するチェックが防止されます。これにより、測定可能なパフォーマンスの向上が得られますパフォーマンスが重要なコードの場合。現在のオブジェクトインスタンスへのアクセスに失敗した場合、正当性の問題が発生することがあります。」
ユーティリティクラス
デザインで意味がない場合は、ユーティリティクラスに移動しないでください。メソッドがToRadians(double degrees)
角度を表すクラスに関連するように、静的メソッドが特定のタイプに関連している場合、そのメソッドがそのタイプの静的メンバーとして存在することは理にかなっています(これはデモンストレーションのための複雑な例です)。
パフォーマンス、名前空間の汚染などはすべて、私の考えでは二次的なものです。何が論理的かを自問してください。メソッドは型のインスタンスで論理的に動作していますか、それとも型自体に関連していますか?後者の場合は、静的メソッドにします。制御できないタイプに関連している場合にのみ、ユーティリティクラスに移動してください。
インスタンスに論理的に作用するが、インスタンスの状態をまだ使用していないメソッドがある場合があります。たとえば、ファイルシステムを構築していて、ディレクトリの概念はわかっていても、まだ実装していない場合は、ファイルシステムオブジェクトの種類を返すプロパティを記述できます。 「ファイル」-それはインスタンスに論理的に関連しているため、インスタンスメソッドである必要があります。これは、メソッドを仮想化する場合にも重要です。特定の実装では状態が必要ない場合がありますが、派生クラスでは必要になる場合があります。(たとえば、コレクションが読み取り専用かどうかを尋ねる-そのコレクションの読み取り専用フォームをまだ実装していない可能性がありますが、それは明らかにタイプではなく、コレクション自体のプロパティです。)
これはあなたのケースでは起こらないと確信していますが、多くの静的メソッドの使用を維持することで苦労しなければならなかったいくつかのコードで見た「悪臭」の1つです。
残念ながら、それらは特定のアプリケーション状態を想定した静的メソッドでした。(確かに、アプリケーションごとに1人のユーザーしかありません!Userクラスに静的変数でそれを追跡させないのはなぜですか?)それらはグローバル変数にアクセスするための栄光の方法でした。また、静的コンストラクター(!)もありましたが、これはほとんど常に悪い考えです。(私はいくつかの合理的な例外があることを知っています)。
ただし、静的メソッドは、オブジェクトのインスタンスの状態に実際には依存しないドメインロジックを除外する場合に非常に役立ちます。コードを読みやすくすることができます。
あなたがそれらを正しい場所に置いていることを確認してください。静的メソッドは他のオブジェクトの内部状態を侵入的に操作していますか?代わりに、それらの動作がそれらのクラスの1つに属しているという良いケースを作ることができますか?懸念を適切に分離していないと、後で頭痛の種になる可能性があります。
これは興味深い読みです:
http://thecuttingledge.com/?p=57
ReSharperは、メソッドを静的にすることを実際に提案しているわけではありません。たとえば、シグネチャに表示されるクラスの1つとは対照的に、そのメソッドがそのクラスにある理由を自問する必要があります...
しかし、ここに再シャープ化ドキュメントが言うことです:http : //confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
特定のシナリオで最も読みやすく直感的な操作を行う必要があります。
実際に起こっている唯一のことは、1つの追加パラメーター(this
)がインスタンスメソッドのスタックにプッシュされていることなので、パフォーマンスの引数は、最も極端な状況を除いて、良いものではありません。
クラス内の複雑なロジックの場合、インスタンスの入力がメソッドシグネチャで明確に定義され、インスタンスの副作用が発生しない、孤立したロジックの作成に役立つプライベートスタティックメソッドが見つかりました。すべての出力は、戻り値または出力/参照パラメーターを介する必要があります。複雑なロジックを副作用のないコードブロックに分解すると、コードの可読性が向上し、開発チームがコードを信頼できるようになります。
一方、ユーティリティメソッドの急増によって汚染されたクラスにつながる可能性があります。いつものように、論理的な名前付け、ドキュメント、およびチームコーディング規則の一貫した適用により、これを軽減できます。
メソッドを静的にすることは、最初にそのクラスのインスタンスを作成しなくても、クラスの外部からメソッドを呼び出すことができることを意味します。これは、サードパーティベンダーのオブジェクトまたはアドオンを操作するときに役立ちます。con.Writeline();を呼び出す前に、まずコンソールオブジェクト「con」を作成する必要があると想像してください。
名前空間の汚染を制御するのに役立ちます。
Class.a_core_function( .. )
vsa_core_function( .. )
Just my tuppence:すべての共有静的メソッドをユーティリティクラスに追加すると、
using static className;
コードを入力するのが速くなり、読みやすくなります。たとえば、私が継承した一部のコードには、「グローバル変数」と呼ばれるものが多数あります。インスタンスクラスであるクラスでグローバル変数を作成するのではなく、すべてをグローバルクラスの静的プロパティとして設定します。乱雑な場合、それは仕事をし、静的名前空間がすでに参照されているので、名前でプロパティを参照できます。
これが良い習慣かどうかはわかりません。私はC#4/5について学ぶことがたくさんあり、リファクタリングするために多くのレガシーコードを持っているので、Roselynのヒントを参考にさせようとしています。
ジョーイ
静的メソッドとインスタンスメソッドの違いをすでに理解していると思います。また、長い答えと短い答えがある場合があります。長い回答はすでに他の人から提供されています。
私の短い答え:はい、 Resharperからの提案があれば、静的メソッドに変換できます。そうすることに害はありません。むしろ、メソッドを静的にすることで、実際にメソッドを保護し、不必要にインスタンスメンバーをそのメソッドにスリップさせないようにします。このようにして、OOP原則「クラスとメンバーのアクセシビリティを最小限に抑える」を実現できます。
ReSharperがインスタンスメソッドを静的メソッドに変換できることを示唆しているとき、それは実際に「なぜこのメソッドはこのクラスに存在していて、実際にはどの状態も使用していないのですか?」だから、それはあなたに思考の糧を与えます。次に、そのメソッドを静的ユーティリティクラスに移動する必要があるかどうかを理解できるのはあなたです。SOLIDの原則によれば、クラスは1つのコア責任のみを持つ必要があります。したがって、この方法でクラスをより適切にクリーンアップできます。場合によっては、インスタンスクラスでもいくつかのヘルパーメソッドが必要になります。その場合は、#regionヘルパー内に保持できます。