更新: @JeremyDWill は、そのパラメーターの 1 つからジェネリック型を派生させることはできないと正しく指摘しました...
デコレーターを「新しいプロパティを追加するサブクラス」と考えると、次のようにすることができます。
public class MyDecorator<T> : T
{
public int MyDecoratorProperty1 { get; set; }
public int MyDecoratorProperty2 { get; set; }
}
MyDecorator<DataBag>
その後、 、 、 などのインスタンスを作成できます。はジェネリック引数の型に固有であり、そのクラスから派生しているMyDecorator<OtherClass>
ため、既存のプロパティにアクセスできます。MyDecorator<>
装飾されたオブジェクトを含むラッパーを作成できます。
public class MyDecorator<T>
{
public MyDecorator(T decoratedObject)
{
this.DecoratedObject = decoratedObject;
}
public T DecoratedObject { get; private set; }
public int MyDecoratorProperty1 { get; set; }
public int MyDecoratorProperty2 { get; set; }
}
利点は、装飾されたプロパティに簡単にアクセスできることです: myObj.MyDecoratorProperty1
. DecoratedObject
欠点は、基本オブジェクトに到達するためにメンバーを通過する必要があることです。
DataBag bag = new DataBag("", null, null);
MyDecorator<DataBag> deco = new MyDecorator<DataBag>(bag);
deco.DecoratedObject.Height = 2;
装飾からサブクラス化できない場合 (たとえば、一度に複数のデコレーターをサポートする必要がある場合)、「添付プロパティ」のようなことを行う必要があります...デコレーター クラスは元の辞書を保持する必要があります。オブジェクトと装飾されたプロパティ。いくつかの拡張メソッドを使用して、これらのプロパティを装飾されたクラスのネイティブ メンバーのように "見える" ようにすることができます。
public static class AttachedDecorator
{
private class Properties
{
public int MyDecoratorProperty1 { get; set; }
public int MyDecoratorProperty2 { get; set; }
}
private static Dictionary<object, Properties> map = new Dictionary<object, Properties>();
public static int GetMyDecoratorProperty1(object obj)
{
Properties props;
if (map.TryGetValue(obj, out props))
{
return props.MyDecoratorProperty1;
}
return -1; // or some value that makes sense if the object has no decorated property set
}
public static int GetMyDecoratorProperty2(object obj) { /* ... */ }
public static void SetMyDecoratorProperty1(object obj, int value)
{
Properties props;
if (!map.TryGetValue(obj, out props))
{
props = new Properties();
map.Add(obj, props);
}
props.MyDecoratorProperty1 = value;
}
public static void SetMyDecoratorProperty2(object obj, int value) { /* ... */ }
}
public static class DecoratorExtensions
{
private static int GetMyDecoratorProperty1(this object obj)
{
return AttachedDecorator.GetMyDecoratorProperty1(obj);
}
private static void SetMyDecoratorProperty1(this object obj, int value)
{
return AttachedDecorator.GetMyDecoratorProperty1(obj, value);
}
// ...
}
コードは次のようになります。
DataBag myData = new DataBag();
myData.SetMyDecoratorProperty1(7);
Console.WriteLine("prop1: {0}", myData.GetMyDecoratorProperty1());