简体   繁体   English

具有多个参数的泛型类中的从属类型约束

[英]Dependent type constraints in generic class with multiple parameters

How can I create a generic with two parameter where the second parameter is dependent on the first. 如何创建具有两个参数的泛型,其中第二个参数取决于第一个参数。 In this case I'm creating a hash class, where I need both the type of the object and the key that identifies it. 在这种情况下,我将创建一个哈希类,在这里我需要对象的类型和标识它的密钥。

Some simplified code for explanation: 一些简化的代码进行解释:

class MyCache<T,Key> : where T is CommonImpl {
   Dictionary<Key,T> cache;

   T Get( Key v ) {
      ...
      var newValue = new T(v);
      return newValue;
   }
}

class ImplA : CommonImpl {
   public ImplA( String key ) { }
}

class ImplB : CommonImpl {
   public ImplB( SomeType key ) { }
}

Where I have two uses of this cache MyCache<ImplA,String> and MyCache<ImplB,SomeType> . 我在这里有两个使用此缓存MyCache<ImplA,String>MyCache<ImplB,SomeType>

I think what you're trying to achieve is something like this: 我认为您要达到的目标是这样的:

public abstract class Base<TKey>
{
    public Base(TKey key) { }
}

public class ImplA : Base<string>
{
    public ImplA(string key) : base(key) {}
}

public class MyCache<TBase, TKey> where TBase : Base<TKey>
{
    public TBase Get(TKey key)
    {
        return (TBase)Activator.CreateInstance(typeof(TBase), key);
    }
}

You can then call 然后你可以打电话

var b = new MyCache<ImplA, string>().Get("hi");

You can't say to a generic class / method it should be Concrete A or B . 您不能对通用类/方法说应该是具体AB You can only tell it it has a common denominator: a base class or an interface. 您只能说它有一个共同的分母:基类或接口。

This is how it should look for example: 例如,这是它的外观:

Interface: 接口:

interface IImpl {
    void SomeCommonMethod();
}

Generic class (here you tell T must implement the interface, so it can be any class that implements the interface). 通用类(在这里,您告诉T必须实现该接口,因此它可以是实现该接口的任何类)。 Also you have to tell it has a default constructor using the new constraint (as noted in comments, it is not possible to tell it has a parameter with type Key ): 另外,您还必须使用new约束来告诉它具有默认构造函数(如注释中所述,不可能告诉它具有类型为Key的参数):

class MyCache<T,Key> : where T : IImpl, new()  {

Key classes: 关键类:

class ImplA : IImpl {
   public ImplA( String key ) { }
}

class ImplB : IImpl {
   public ImplB( SomeType key ) { }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM