2016-05-08 9 views
1

C#でTUIライブラリを開発しています。表示オブジェクトのカラーテーマを行う方法についてアドバイスが必要です。すべてのこのインターフェイスから継承し、画面上に描画することができるオブジェクト:クラスに抽象クラスの固有の実装を含める/使用させる

public interface IDrawable 
    { 
     Area ScreenArea { get; } 
     List<char[]> DisplayChars { get; } 
     //some other properties... 

    } 

いうかは、より具体的には、各描画可能なオブジェクトのためのインターフェースは、このインターフェース(IWindowIDrawableある)を実装します。各IDrawableが領域構造体によって表されるコンソールウィンドウの指定された部分に描画される:

public struct Area 
    { 
     public readonly int EndX; 
     public readonly int EndY; 
     public readonly int Height; 
     public readonly int StartX; 
     public readonly int StartY; 
     public readonly int Width; 

     public Area(int startX, int endX, int startY, int endY) 
     { 
      StartX = startX; 
      EndX = endX; 
      StartY = startY; 
      EndY = endY; 
      Height = endY - startY; 
      Width = endX - startX; 
     } 

     /// <summary> 
     /// Get the overlapping area between this area and another. 
     /// </summary> 
     /// <param name="refArea"></param> 
     /// <returns>Overlap area relative to the upper left corner of the ref area.</returns> 
     public Area OverlapWith(Area refArea) 
     { 
      //.... 
     } 
    } 

オブジェクトの実際の描画はDisplayCharsの各要素にConsole.Write()を呼び出す静的Displayクラスのメソッドによって処理されます。 IDrawableから継承した各クラスは、その領域を別々の色域に分割するための独自のルールを強制的に適用することを願っています。たとえば、ポップアップウィンドウには、外枠、その外側の境界線)、およびその内側領域。

私はしばらく私の頭の中でこれをやり遂げる方法を捨ててきました。どんな文字をどの色で書き込むかのルールを入れるには、タイプをColorSchemeにする必要があります。私はこれを行う最善の方法は、色を別々に適用できる "サブ領域"のリストを含む抽象クラスにすることであると判断した。

非抽象度の各IDrawableは、ColorSchemeから継承する独自のクラスを実装する必要があります。たとえば、抽象的Window : IWindowクラスはそのような実装を持たないが、PopupWindow : Windowクラスは対応するタイプがPopupWindowColorScheme : ColorSchemeでなければならず、PopupWindowの作成者はクラス 'Areaを分割する方法を定義します。各PopupWindowには、特定の色を含むこのタイプの独自のインスタンスがあります。

これは可能ですか?そうでない場合は、IDrawableタイプの作者に領域を着色可能な領域に分割する方法を指定させる別の方法がありますか?

答えて

0

あなたは(PopupWindowColorSchemeを使用することができIDrawableの例えば複数の異なる実装)ColorSchemeユニーク実装を持っている各IDrawableを強制することはできません。しかし、あなたはこのように、あなたのインターフェイスを実装するための追加要件を追加するためにgeneric type constraintsを使用することができます。

public interface IDrawable<TColorScheme> 
    where TColorScheme : ColorScheme 
{ 
    Area ScreenArea { get; } 
    List<char[]> DisplayChars { get; } 
    //some other properties... 
    TColorScheme ColorScheme { get; } 
} 

さて、IDrawableのすべての実装は、使用するColorSchemeのタイプを指定する必要があります。しかし、消費者は単にIDrawable<ColorScheme>を実装することができます(あなたの要件に応じて)目的を破ることができます。 ColorSchemeが抽象的であるため、ここで

public interface IDrawable<TColorScheme> 
    where TColorScheme : ColorScheme, new() 
{ 
} 

public abstract class ColorScheme { } 

、およびジェネリック型制約は、パラメータなしのコンストラクタ(new())、ColorScheme自体をパラメータとして使用することはできません実現のために提供されるタイプのパラメータが必要です:私たちは少し先に進むことができます。すべての実装クラスは、パブリックのパラメータのないコンストラクタを提供するColorSchemeのカスタム実装を指定する必要があります。

しかし、我々はさらに行くことができます:ここで

public interface IDrawable { } 
public interface IDrawable<TDrawable, TColorScheme> : IDrawable 
    where TDrawable : IDrawable, new() 
    where TColorScheme : ColorScheme<TDrawable>, new() 
{ 
    object ScreenArea { get; } 
    List<char[]> DisplayChars { get; } 
    //some other properties... 
    TColorScheme ColorScheme { get; } 
} 

public abstract class ColorScheme<TDrawable> 
    where TDrawable : IDrawable, new() 
{ 
} 

は、IDrawableの各実装では、それはまた、ColorSchemeを使用して、それが適用されるものをIDrawableを指定しているものColorScheme指定する必要があります。また、それぞれがパラメータのないコンストラクタを必要とするため、どちらも共通の基本型を指定できません。これを実装することは、今少し奇妙に見える:

public class MyDrawable : IDrawable<MyDrawable, MyColorScheme> { } 

public class MyColorScheme : ColorScheme<MyDrawable> { } 

それは(例えばMyOtherDrawable : MyDrawableMyColorSchemeを使用しています)、再利用可能なColorSchemeまたはIDrawableを実施することは可能です。しかし、私の意見では、これは実装が面倒で退屈になり始めています。一般的に、技術的な理由がない限り、にはタイプ制限を使用していますが、私はそれを使用しないでください。

+0

これは完璧です!すばやい応答ありがとう:)私はちょうどDrawScreeneは、Drawメソッドが画面に書き込む各文字の色をチェックして設定する必要がないような方法で、ColorSchemeの外観を把握する必要があります。 – thetiniestmouse

+0

貧弱な継承階層設計のために、わずかな問題です。私は現在、 'IDrawable'から継承した抽象クラスと、' WindowManager'や 'ControlManager'のようなクラスがそれぞれのインタフェースを介してそれぞれの型を扱うことができるというアイデアを抽象ベースで間接的に継承した特定の型を持っています。それらはdrawablesとして。キャストを使用して、新しいタイプのウィンドウを作成するときに 'IDrawable'と' IWindow'の両方を使用するなど、カスタムタイプを作成する人に頼りすぎるのでしょうか? – thetiniestmouse

+0

@thetestestmouseその場合、 'ColorScheme'以外のすべてのコアプロパティとメソッド*を指定する非ジェネリックインターフェイス' IDrawable'と 'ColorScheme 'を提供するサブインターフェイス' IDrawable :IDrawable'を使うことをお勧めします。 '特有の機能です。ベース 'ColorScheme'を公開し、' IDrawable 'を' new T ColorScheme {get; } '。 (これは 'IEnumerable :IEnumerable'がどのように動作するかと似ています) –

関連する問題