Reputation: 31861
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>
.
Upvotes: 1
Views: 1222
Reputation: 28107
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");
Upvotes: 2
Reputation: 156948
You can't say to a generic class / method it should be Concrete A
or B
. 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). 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
):
class MyCache<T,Key> : where T : IImpl, new() {
Key classes:
class ImplA : IImpl {
public ImplA( String key ) { }
}
class ImplB : IImpl {
public ImplB( SomeType key ) { }
}
Upvotes: 1