gpt4 book ai didi

c# - 具有通用基类的装饰器

转载 作者:行者123 更新时间:2023-11-30 18:10:14 24 4
gpt4 key购买 nike

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

public class Decorator<T> : T
{
public object AdditionalInformation {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;
}
}

但这不一样,因为隐式转换只是一种方式。例如,他不能将其用作方法的返回类型,因为附加信息在隐式转换后会丢失。

有没有人有更好的主意?

最佳答案

如果您可以从某个基类派生所有可装饰类,那么您可以尝试在该基类中存储装饰器并使其信息可恢复。这是保证包含一些错误的示例代码,但您可以明白这一点。

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>>();

如果无法派生,则必须将信息存储在某个静态类中。但是,正如 wcoenen 评论的那样,您需要清除该信息,否则会发生内存泄漏。清除很容易出错,而且并非总是可行,因此最好采用第一种方法。例如(不是线程安全的,如果你打算在多线程应用程序中使用它,你必须添加锁定):

static public class Decorators
{
static Dictionary<object,Dictionary<Type,object>> instance = new Dictionary<object,Dictionary<Type,object>>();
public static void AddDecorator<T,D>(this T obj, D decor)
{
Dictionary<Type,object> d;
if (!instance.TryGetValue(obj, out d))
{
d = new Dictionary<Type,object>();
instance.Add(obj, d);
}
d[typeof(D)]=decor;
}

public static D GetDecorator<T,D>(this T obj)
{
// here must be double TryGetValue, but I leave it to you to add it
return (D) instance[obj][typeof(D)];
}

public static T ClearDecorators(this T obj) { instance.remove(obj); }

}

// Decorator<T> code stays the same, but without type constraint

关于c# - 具有通用基类的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1694813/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com