2009-05-05 9 views
36

私は最近、静的抽象メソッドが必要な問題に遭遇しました。私はなぜそれが不可能であるか知っていますが、この制限を回避するにはどうしたらいいですか?C#、メソッドのような 'static abstract'を実装しました

たとえば、説明文字列を持つ抽象クラスがあります。この文字列は、すべてのインスタンスに共通ですので、それは静的なマークが、私は、私は抽象としてそれをマークして、このクラスから派生したすべてのクラスが自分のDescriptionプロパティを提供することを要求したいされています

abstract class AbstractBase 
{ 
    ... 
    public static abstract string Description{get;} 
    ... 
} 

それはしませんもちろんコンパイルする。私はインターフェイスを使用することを考えましたが、インターフェイスに静的メソッドシグニチャが含まれていない可能性があります

私は単純に非静的にする必要がありますし、常にそのクラス固有の情報を取得するインスタンスを取得する必要がありますか?

アイデア?

+0

http://stackoverflow.com/questions/763344/c-virtual-or-abstract-static-methods/763364#763364 –

+0

[C#で抽象静的メソッドを使用できないのはなぜですか? ?](https://stackoverflow.com/questions/3284/why-cant-i-have-abstract-static-methods-in-c) –

+0

[仮想静的プロパティの実装方法](https:///stackoverflow.com/questions/15346631/how-to-implement-virtual-static-properties) – peterh

答えて

5

静的と抽象的な組み合わせは意味がありません。静的の背後にあるアイデアは、問題のメンバーを使用するためにクラスのインスタンスを提示する必要はありません。抽象的には、具体的な実装を提供する派生クラスのインスタンスが必要です。

なぜこのような組み合わせが必要なのか分かりますが、 'this'やその他の非静的メンバーの実装の使用を拒否するのが唯一の効果です。つまり、親クラスは、抽象メンバまたは「静的抽象」メンバを呼び出す間に根本的な違いがないのに(どちらの実装でどの実装を使用するかを判断するための具体的なインスタンスが必要なため)、派生クラスの実装の制限を指示します。

+0

私は再び状況を考えましたが、それは本当だと言います... public abstract string {get;} public string {get {return "Izeeeeeeeeh";}}のように実装されています。 – Calmarius

+71

それは無意味ではありません。あなたがフレームワークを設計しているとします。あなたは、何かを実装するクラスがコンパイル時の既知のデータを公開することを要求します。たとえば、「フレンドリーなクラス名」です。コンパイラがすべてのISomethingsにこのプロパティがあることを確認する必要があります。これを今したい場合は、インスタンスプロパティを使用する必要があります。これは、型を照会するのではなく、インスタンスを作成することを意味します。それは吸う。 –

+3

私は@RyanBarrettに同意します。フレームワーク設計のために、コンストラクターが派生クラスで関数を提供するように強制するのは便利ですが、インスタンスが存在しない状態で関数が静的に実行されることを契約で記述します。 –

31

これを行う場所は「属性」です。

例:

[Name("FooClass")] 
class Foo 
{ 
} 
+0

Clever。 。 。 – Shog9

+3

確かに...公開静的なDescriptionプロパティは、よりアクセスしやすくするために属性値を取得することもできます。 –

+0

実行時にどのように動作するか知りたいですか。属性は何とかインスタンスvarとして終了しますか?私はリフレクションの前にカスタム属性を読みましたが、CLRがそれらをどのように処理しているのか分かりません。 –

3

それがインスタンスで呼び出さなければならない場合には、静的ではありません。

インスタンスで呼び出さない場合は、多型性はありません(つまり、ChildA.Descriptionは、言語に関する限りChildB.Descriptionとは完全に無関係です)。

5

静的である場合、変数のインスタンスは1つしかありません。派生クラスで静的変数を使用して達成したいことができれば、継承がどのように役立つかはわかりません。個人的には、インスタンスvarを避けるために遠くに行っていると思います。

なぜ古典的な方法ではないのですか?

abstract class AbstractBase 
{ 
    protected string _Description = "I am boring abstract default value"; 
} 

class Foo : AbstractBase { 

    public Foo() { 
     _Description = "I am foo!"; 
    } 
} 
5

あなたは賢明Descriptionプロパティを実装する実装に延期気にしない場合、あなたは、単に

public abstract string ClassDescription {get; } 
// ClassDescription is more intention-revealing than Description 

とクラスは、このようなものだろう実装することが可能です。

static string classDescription="My Description for this class"; 
override string ClassDescription { get { return classDescription; } } 

をそれから、あなたのクラスは説明の契約に従う必要がありますが、あなたはそれを分かりやすくするために彼らに任せます。実装をオブジェクト指向の方法で指定する方法はありません(残酷で壊れやすいハックを除く)。

しかし、私の考えでは、この説明はクラスメタデータなので、他の人が記述しているように属性メカニズムを使用することをお勧めします。反射の多重使用が特に心配な場合は、関係する属性を反映するオブジェクトを作成し、タイプと説明の間に辞書を格納します。これにより、リフレクションが最小限に抑えられます(ランタイムタイプの検査以外は悪いことではありません)。ディクショナリは、通常はこの情報が必要なクラスのメンバーとして、またはドメイン全体のクライアントがシングルトンまたはコンテキストオブジェクトを介して必要とする場合は、そのメンバーとして格納できます。

0

"抽象"ベースメソッドをExceptionにスローすると、オーバーライドしないで子クラスに対してこのメ​​ソッドを呼び出そうとすると、開発者は "警告"されます。

欠点は、クラスを拡張してこのメ​​ソッドを使用しないことです。次に、他の回答を参照してください。

関連する問題