2013-02-21 15 views
10

私は別のアセンブリのメソッドで使用されるAPIに抽象クラスを持っています。私はその後、事がインターフェースだった場合、それはより良いデザインだろうことを決めたインターフェイスは型を宣言できません

abstract public class Thing 
{ 
    public enum Status { Accepted, Denied, Pending }; 
    abstract public Status status { get; private set; } 
    etc... 
} 

:クラスは、その中に定義されたネストされた列挙型、このようなビットを持っています。しかし、私はこれを行うことはできません。

public interface Thing 
{ 
    enum Status { Accepted, Denied, Pending }; 
    Status status { get; } 
    etc... 
} 

これはエラーメッセージ生成「のインターフェイスは、型を宣言することはできませんが。」しかし、インターフェイスの外でenumの定義を動かすと、カプセル化が破られてしまいます(Status型は本当にThingに属し、意味がありません)。もっと重要なのは、これを使用する他の多くのアセンブリです。あなたはどんな解決策も考えられますか?

+0

カプセル化を使用してカプセル化することはできませんが、あなたはクラスとして「Thing」のままにしておいてください。抽象基本クラスには何も問題はありません。 –

+0

この非常に疑問が尋ねられた他の場所がいくつか見つかりましたが、このコメントには良い選択肢があります。 http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/14beb8d1-63d9-42f7-b036-eb9ebb106d08 基本的には、別の場所で列挙型を宣言するか、代わりにクラスを使用することができますインターフェイスの....それはそれについてです。あなたがしようとしていることを正確に行う方法はありません。 – Nevyn

+4

"カプセル化"の議論は私の論証ではなく、とにかく公に入れ子にされた型を取り除くよう助言します。もしそれが世界にさらされることができれば、そのように扱います。 –

答えて

13

エラーが示すように、Statusの定義をインターフェイスの外にプルするだけで済みます。私はそれがカプセル化を破ることを理解しますが、実際にはこれを回避する方法はありません。 Statusの名前をThing - ThingStatusと強く関連付けることを示すように変更することをお勧めします。

3

はい、解決策は、このような実装が必要な場合は抽象クラスを使用することです。抽象クラスは悪いデザインではなく、このような状況では確かに有用です。

インターフェイスを使用することを強くお勧めする場合は、p.su.gzの解決策を踏まなければならず、2つのルールを破る必要があります(実際はガイドラインにすぎません)。

1

abstractクラスとinterfaceは異なるものです。 abstarctクラスは抽象度が高く、ドメインモデルよりも高く、インターフェースはドメインエンティティの契約(動作)です。必要に応じて、両方でソリューションを使用できます。具体的なシナリオでは、statusは単なる動作状態ではありません。私は抽象クラスがより信頼できる選択だと思う。

+0

このような視点をお寄せいただきありがとうございます。興味深い点として、抽象クラスが、構文の一部としてインターフェースを持たない言語のインターフェースとしてどのように使用されているかに注目してください(C++は明白な例です)。 –

+0

@KlitosKyriacouインターフェイスとして抽象クラスを使用するには、すべてのメンバーを抽象クラスとして宣言します。しかし、これはC#ではまったく同じではありません。 –

関連する問題