40

共通のインターフェイスを実装する一連のクラスを開発しています。私のライブラリのコンシューマは、これらのクラスのそれぞれが特定の静的関数のセットを実装することを期待するものとします。関数の1つが実装されていない場合をコンパイラがキャッチできるように、これらのクラスを装飾することはできますか。

消費するコードをビルドするときに最終的にキャッチされることを私は知っています。また、一種のファクトリ クラスを使用してこの問題を回避する方法も知っています。

クラスで静的関数を要求するための構文/属性があるかどうかを知りたいだけです。

Ed混乱を避けるために「インターフェース」という単語を削除しました。

4

9 に答える 9

35

いいえ、C# ではこれに対する言語サポートはありません。すぐに思いつく回避策が 2 つあります。

  • 実行時にリフレクションを使用します。交差した指と希望...
  • メソッドを宣言するインターフェースを実装するために、シングルトン/デフォルトインスタンス/類似を使用します

(更新)

実際、単体テストを行っている限り、最初のオプションは、(私のように) 厳格な「静的型付け」のバックグラウンドを持っている場合に考えられるほど悪くはありません。事実は次のとおりです。動的言語では問題なく動作します。実際、これはまさに私の汎用演算子コードがどのように機能するかです -静的演算子があることを願っています。そうしないと、実行時に適切に嘲笑されますが、コンパイル時にチェックすることはできません。

于 2009-02-23T14:16:43.483 に答える
23

いいえ。基本的には、一種の「静的ポリモーフィズム」を求めているようです。これは C# には存在しませんが、generics に関して有用な一種の「静的インターフェイス」概念を提案しました。

できることの1 つは、単純な単体テストを作成して、特定のアセンブリ内のすべての型がルールに従っていることを確認することです。他の開発者もインターフェイスを実装する場合は、そのテスト コードを共通の場所に配置して、インターフェイスを実装するすべてのユーザーが独自のアセンブリを簡単にテストできるようにすることができます。

于 2009-02-23T14:21:55.217 に答える
8

これは素晴らしい質問であり、私のプロジェクトで遭遇したものです。

一部の人々は、インターフェイスと抽象クラスはポリモーフィズムのためだけに存在し、型に特定のメソッドの実装を強制するためではないと考えています。個人的には、ポリモーフィズムが主なユースケースであり、強制的な実装は二次的なものだと考えています。私は強制実装手法をかなり頻繁に使用しています。通常、テンプレート パターンを実装するフレームワーク コードに表示されます。ベース/テンプレート クラスはいくつかの複雑なアイデアをカプセル化し、サブクラスは抽象メソッドを実装することによって多数のバリエーションを提供します。実用的な利点の 1 つは、抽象メソッドが、サブクラスを実装する他の開発者にガイダンスを提供することです。Visual Studio には、メソッドをスタブ化する機能もあります。これは、保守開発者が数か月または数年後に新しいサブクラスを追加する必要がある場合に特に役立ちます。

欠点は、C# では、これらのテンプレート シナリオの一部が具体的にサポートされていないことです。静的メソッドは 1 つです。もう 1 つはコンストラクターです。理想的には、ISerializable は開発者に保護されたシリアル化コンストラクターの実装を強制する必要があります。

おそらく最も簡単な方法は、(前述のように) 自動テストを使用して、目的の型に静的メソッドが実装されていることを確認することです。すでに述べたもう 1 つの実行可能なアイデアは、静的分析ルールを実装することです。

3 番目のオプションは、 PostSharpなどのアスペクト指向プログラミング フレームワークを使用することです。PostSharp は、アスペクトのコンパイル時の検証をサポートしています。コンパイル時にアセンブリを反映する .NET コードを記述して、任意の警告とエラーを生成できます。通常、アスペクトの使用法が適切であることを検証するためにこれを行いますが、テンプレート ルールの検証にも使用できない理由がわかりません。

于 2009-07-22T20:30:24.170 に答える
4

残念ながら、いいえ、言語に組み込まれているようなものはありません。

于 2009-02-23T14:12:22.167 に答える
3

これに対する言語サポートはありませんが、静的分析ツールを使用して強制することができます。たとえば、クラスの属性またはインターフェイスの実装を検出し、特定の静的メソッドの存在をチェックする FxCop のカスタム ルールを作成できます。

于 2009-02-23T14:41:47.633 に答える
1

シングルトン パターンがすべての場合に役立つわけではありません。私の例は、私の実際のプロジェクトからのものです。考案されたものではありません。

サードパーティ ORM のクラスから継承するクラス (「ウィジェット」と呼びましょう) があります。静的メソッドが宣言されていることを確認するためだけに Widget オブジェクトをインスタンス化する (したがって、db に行を作成する) と、クリーンアップしようとしているものよりも大きな混乱が生じます。

この余分なオブジェクトをデータ ストアに作成すると、ユーザーや計算などから非表示にする必要があります。

C# のインターフェイスを使用して、一連のクラスに共通の機能を確実に実装しています。

これらの機能を実装するメソッドの中には、インスタンス データを実行する必要があるものがあります。これらのメソッドをインスタンス メソッドとしてコーディングし、C# インターフェイスを使用してそれらがクラスに存在することを確認します。

これらのメソッドの一部はインスタンス データを必要としないため、静的メソッドです。静的メソッドを使用してインターフェイスを宣言できれば、コンパイラは、インターフェイスを実装するクラスにこれらのメソッドが存在するかどうかを確認できます。

于 2009-06-26T12:01:48.087 に答える
0

Marc Gravellが提案したように、必要なものに近づくためのアプローチはシングルトンです。

とりわけ、インターフェースを使用すると、クラスにある程度の抽象化を提供できるため、実装するタイプに関係なく、特定のAPIを使用できます。ただし、静的クラスを使用するにはそのタイプを知る必要があるので、なぜそのクラスに一連の関数を実装するように強制する必要があるのでしょうか。

たぶん、[ImplementsXXXInterface]のようなカスタム属性を使用して、この属性を持つクラスが実際に必要なインターフェイスを実装していることを確認するための実行時チェックを提供できますか?

于 2009-02-23T14:57:15.867 に答える
0

これらのコンパイラ エラーが発生した直後の場合は、次の設定を検討してください。

  1. インターフェイスでメソッドを定義します。
  2. メソッドはabstractで宣言します。
  3. public static メソッドを実装し、abstract メソッドのオーバーライドで単に static メソッドを呼び出すようにします。

少し余分なコードですが、誰かが必要なメソッドを実装していないことがわかります。

于 2011-11-04T21:14:25.703 に答える
0

いいえ、この機能には意味がありません。インターフェイスは基本的に、多重継承の縮小形式です。これらは、非静的仮想メソッドを子孫クラスで適切に呼び出すことができるように、仮想関数テーブルを設定する方法をコンパイラに指示します。静的メソッドは仮想化できないため、それらにインターフェイスを使用しても意味がありません。

于 2009-02-23T14:21:45.000 に答える