通过几个派生类传递类型参数,以便在通用静态构造函数中使用

时间:2015-05-20 17:23:12

标签: c# generics

我有一些针对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,我不愿意为每个方法复制这些方法,因此我需要:

  • 在我现在尝试或
  • 从内存继承MemoryStructs
  • 将所有方法放入Memory类,命名为ReadBytes(Memory)和ReadStructs(MemoryStructs)

3 个答案:

答案 0 :(得分:2)

InstanceA<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; }
}