Stack Overflowで以前に説明したように、マーカーインターフェイス(メンバーのないインターフェイス)よりも属性を優先する必要があります。MSDNのインターフェイスデザインの記事でも、この推奨事項が主張されています。
マーカーインターフェイス(メンバーのないインターフェイス)の使用は避けてください。
カスタム属性は、タイプをマークする方法を提供します。カスタム属性の詳細については、「カスタム属性の記述」を参照してください。コードが実行されるまで属性のチェックを延期できる場合は、カスタム属性が推奨されます。シナリオでコンパイル時のチェックが必要な場合、このガイドラインに準拠することはできません。
この推奨事項を適用するためのFxCopルールもあります。
空のインターフェースは避けてください
インターフェイスは、動作または使用契約を提供するメンバーを定義します。インターフェイスによって記述された機能は、継承階層のどこにタイプが表示されているかに関係なく、どのタイプでも採用できます。タイプは、インターフェースのメンバーに実装を提供することによってインターフェースを実装します。空のインターフェースはメンバーを定義しないため、実装可能なコントラクトを定義しません。
タイプに実装が期待される空のインターフェイスがデザインに含まれている場合は、インターフェイスをマーカーとして使用しているか、タイプのグループを識別する方法を使用している可能性があります。この識別が実行時に発生する場合、これを実現する正しい方法は、カスタム属性を使用することです。属性の有無、または属性のプロパティを使用して、ターゲットタイプを識別します。コンパイル時に識別を行う必要がある場合は、空のインターフェイスを使用できます。
この記事では、警告を無視する可能性がある理由を1つだけ述べています。それは、型のコンパイル時の識別が必要な場合です。(これは、インターフェイスデザインの記事と一致しています)。
コンパイル時にインターフェイスを使用してタイプのセットを識別する場合は、このルールから警告を除外しても安全です。
実際の質問があります。Microsoftは、フレームワーククラスライブラリの設計における独自の推奨事項に準拠していませんでした(少なくともいくつかのケースでは):IRequiresSessionStateインターフェイスとIReadOnlySessionStateインターフェイス。これらのインターフェイスは、ASP.NET Frameworkによって使用され、特定のハンドラーのセッション状態を有効にする必要があるかどうかを確認します。明らかに、コンパイル時の型の識別には使用されません。なぜ彼らはそれをしなかったのですか?私は2つの潜在的な理由を考えることができます:
マイクロ最適化:オブジェクトがインターフェースを実装しているかどうかのチェック(
obj is IReadOnlySessionState
)は、リフレクションを使用して属性(type.IsDefined(typeof(SessionStateAttribute), true)
)をチェックするよりも高速です。ほとんどの場合、この違いはごくわずかですが、ASP.NETランタイムのパフォーマンスが重要なコードパスでは実際に問題になる可能性があります。ただし、各ハンドラータイプの結果をキャッシュするなど、回避策があります。興味深いのは、ASMX Webサービス(同様のパフォーマンス特性の影響を受ける)が実際にこの目的で属性のEnableSession
プロパティを使用することです。WebMethod
インターフェイスの実装は、サードパーティの.NET言語による属性で型を装飾するよりもサポートされる可能性が高い可能性があります。ASP.NETは言語に依存しないように設計されており、ASP.NETは、ディレクティブの属性に基づいて前述のインターフェイスを実装する型のコードを生成します( CodeDomを使用してサードパーティの言語で生成される可能性があります)。属性の代わりにインターフェースを使用する意味があります。
EnableSessionState
<%@ Page %>
属性の代わりにマーカーインターフェイスを使用する説得力のある理由は何ですか?
これは単に(時期尚早?)最適化ですか、それともフレームワーク設計の小さな間違いですか?(彼らは反射が「赤い目を持つ大きな怪物」だと思いますか?)考え?