C# 具有泛型基类的装饰器

C# 具有泛型基类的装饰器,c#,generics,C#,Generics,我的一位同事上周问我,在C#中是否可以从泛型参数扩展泛型类。他说C++是可能的。 他想要的其实是有道理的。他想要一个泛型装饰器用附加信息注释任意类。比如: public class Decorator<T> : T { public object AdditionalInformation {get:set;} } 公共类装饰器:T { 公共对象附加信息{get:set;} } 所以他现在可以在任何地方使用这个通用的装饰器,而不是T 我能得到的最相似的东西是一个容器类,它

我的一位同事上周问我,在C#中是否可以从泛型参数扩展泛型类。他说C++是可能的。 他想要的其实是有道理的。他想要一个泛型装饰器用附加信息注释任意类。比如:

public class Decorator<T> : T
{
    public object AdditionalInformation {get:set;}
}
公共类装饰器:T
{
公共对象附加信息{get:set;}
}
所以他现在可以在任何地方使用这个通用的装饰器,而不是T

我能得到的最相似的东西是一个容器类,它包含原始对象、附加信息和隐式转换

public class Decorator<T>
{
    private readonly T _instance;

    public Decorator(T instance)
    {
        _instance = instance;
    }

    public T Instance
    {
        get { return _instance; }
    }
    public object AdditionalInformation { get; set; }

    public static implicit operator T(Decorator<T> deco)
    {
        return deco._instance;
    }
}
公共类装饰器
{
私有只读T_实例;
公共装饰器(T实例)
{
_实例=实例;
}
公共T实例
{
获取{return\u instance;}
}
公共对象附加信息{get;set;}
公共静态隐式运算符T(Decorator deco)
{
返回deco.\u实例;
}
}
但这并不相同,因为隐式转换只是一种方式。例如,他不能将其用作方法的返回类型,因为在隐式转换之后,附加信息将丢失

public class Decorator<T>
{
    private readonly T _instance;

    public Decorator(T instance)
    {
        _instance = instance;
    }

    public T Instance
    {
        get { return _instance; }
    }
    public object AdditionalInformation { get; set; }

    public static implicit operator T(Decorator<T> deco)
    {
        return deco._instance;
    }
}

有人有更好的主意吗?

如果可以从某个基类派生出所有可分解类,那么可以尝试在该基类中存储decorator并使其信息可恢复。下面是保证包含一些错误的示例代码,但您可以理解

public class Decorable
{
    Dictionary<Type,object> decors = new Dictionary<Type,object>();
    public void AddDecorator<D>(D decor) { decors[typeof(D)] = decor; }
    public D GetDecorator<D>()
    {
        object value;
        if (decors.TryGetValue(typeof(D), out value))
            return (D)value;
        else
            return default(D);
    }

}

public class Decorator<T> where T: class, Decorable
{
    private readonly T _instance;
    public Decorator(T instance)
    {
        _instance = instance;
        instance.AddDecorator(this);
    }

    public T Instance
    {
        get { return _instance; }
    }

    public object AdditionalInformation { get; set; }
}
// use it like this
Decorator<MyClass> myDecor = myObj.GetDecorator<Decorator<MyClass>>();
公共类可分解
{
字典花色=新字典();
公共空间装饰(D装饰){decors[typeof(D)]=装饰;}
公共D GetDecorator()
{
目标价值;
if(花色TryGetValue(类型(D),输出值))
返回(D)值;
其他的
返回默认值(D);
}
}
公共类装饰器,其中T:class,可分解
{
私有只读T_实例;
公共装饰器(T实例)
{
_实例=实例;
AddDecorator(this);
}
公共T实例
{
获取{return\u instance;}
}
公共对象附加信息{get;set;}
}
//像这样使用它
Decorator myDecor=myObj.GetDecorator();
如果无法派生,则必须将信息存储在某个静态类中。但是,正如wcoenen所评论的那样,您需要清除这些信息,否则会导致内存泄漏。清除容易出错,而且不总是可能的,所以最好使用第一种方法。例如(不是线程安全的,如果您计划在多线程应用程序中使用锁,则必须添加锁):

静态公共类修饰符
{
静态字典实例=新字典();
公共静态虚空装饰器(此T obj,D装饰)
{
词典d;
如果(!instance.TryGetValue(obj,out d))
{
d=新字典();
实例.Add(obj,d);
}
d[类型(d)]=装饰;
}
公共静态D GetDecorator(此T对象)
{
//这里必须是双TryGetValue,但我让您添加它
返回(D)实例[obj][typeof(D)];
}
公共静态T ClearDecorators(此T obj){instance.remove(obj);}
}
//装饰器代码保持不变,但没有类型约束

类似的问题:嗯,有点!我正在寻找一种方法来制作这个泛型装饰器,而不是了解为什么不可能使用泛型基类。一个保持对象到装饰器映射的静态类将导致装饰对象永远不会被垃圾收集。添加RemoveDecorator来解决这个问题只会让事情变得更复杂:什么时候应该调用它,由谁调用?您将介绍一整类内存泄漏错误。感谢您发现这一点,wcoenen。你完全正确,所以我更新了答案。