我有一些针对multiton或对象池的通用模板。
public class A<TC> where TC : class, new()
{
protected static ConcurrentDictionary<object, TC> _instances = new ConcurrentDictionary<object, TC>();
public static TC Instance(object key)
{
return _instances.GetOrAdd(key, k => new TC());
}
}
// One level inheritance works as expected
public class B : A<B>
{
public virtual int Demo() { return 1; }
}
// Class C is example of what I want
// How to override method from B, pass C to A and use it in GetInstance?
public class C : B<C>
{
public override int Demo() { return 2; }
}
问题:我希望C类从B覆盖方法,如何通过子类链传递类型参数“C”以使用方法Instance()来自A,是吗可能吗?
我试图修改B,但似乎它使它成为通用的,并且不允许实例化B:
public class B<TC> : A<TC> where TC : class, new()
{
public virtual int Demo() { return 1; }
}
更新:我的想法是拥有通用的静态构造函数,然后我从它中派生类内存,它与内存映射文件一起工作,但是这个类只能读写字节序列,因此,我创建了从Memory派生的类MemoryStructs,这个类可以读写整个结构,当然,我可以把所有这些方法都放到Memory中,但我认为将它们逻辑分割可能是有用的,因此,我有这样的继承chain:BaseClass&gt;记忆&gt; MemoryStructs
Memory和MemoryStructs类有方法OpenMemory和CloseMemory,我不愿意为每个方法复制这些方法,因此我需要:
答案 0 :(得分:2)
Instance
是A<TC>
的静态方法,因此在Instance
中甚至不存在您可以覆盖的B
方法(即使可以,TC
那时类型参数将绑定到B
,因此返回C
的方法将是一种不同的方法。)
因此,您拨打Instance
的方式是使用A<TC>.Instance(key)
,其中TC
是实际类型。例如:
B objectB = A<B>.Instance(key)
C objectC = A<C>.Instance(key)
请注意,并发字典对于每个类型参数TC
是单独的,因此A<B>
和A<C>
不共享同一个字典;它们是具有不同静态成员的不同类型。
答案 1 :(得分:1)
也许你需要链中另一个班级?
public class B1<T> : A<B1<T>>
{
public virtual int Demo() { return 1; }
}
public class B2 : B1<B2>
{
// Something that C does not do
}
public class C : B1<C>
{
public override int Demo() { return 2; }
}
修改强>
似乎你想要继承B的一些功能并在C中传递一个类型参数,同时你想将B定义为非泛型类,这是不可能的,B必须是非泛型的,你不要没有C:B&lt; C&gt;了:
public class B : A<B>
{
public virtual int Demo() { return 1; }
}
public class C : B
{
public override int Demo() { return 2; }
}
或者它必须是通用的,因此您不能将B作为类型参数传递给A:
public class B<T> : A<T>
{
public virtual int Demo() { return 1; }
}
public class C : B<T>
{
public override int Demo() { return 2; }
}
或者您可以选择使用合成模式并在C中创建B的实例,以便您可以在C中使用它的功能:
public class B : A<B>
{
public virtual int Demo() { return 1; }
}
public class C : A<C>
{
private B b = new B();
public override int Demo() {
// Maybe use b here
return 2;
}
}
答案 2 :(得分:1)
@David Amo绝对正确。也许这就是你追求的目标?
public abstract class A<TC> where TC : class, new()
{
protected static ConcurrentDictionary<object, TC> _instances =
new ConcurrentDictionary<object, TC>();
public static TC Instance(object key)
{
return _instances.GetOrAdd(key, k => new TC());
}
public abstract int Demo();
}
public class B : A<B>
{
public override int Demo() { return 1; }
}
public class C : A<C>
{
public override int Demo() { return 2; }
}