-1

Is it possible to have a generic type parameter that requires a type parameter?

i.e.

public abstract class ClassA<T>
{}
public class ClassB<T>:ClassA<T>
{}
...
public void MethodA<T>() where T:ClassA, new()
{
  T<string> x=new T<string>();
}
...
MethodA<ClassB>();

This produces an error because ClassB requires a type parameter on the last line.

Is there a missing piece of syntax I can use that will make this work?

(Side note, This question is largely theoretical since I can probably achieve what I want without the above but the above would certainly make things cleaner in the user-side code, though probably messier inside MethodA since reflection will almost certainly come in to play at some point)

DJL
  • 1,821
  • 3
  • 17
  • 31
  • 1
    You've got some code which doesn't work, but you haven't described the larger problem you're trying to solve - which makes it hard to give you a good solution. For example, you *might* want to declare a non-generic `ClassA` as a base type for `ClassA`... or you might not. – Jon Skeet Feb 04 '14 at 10:39

2 Answers2

0

You have to add additional generic parameter to your MethodA:

public void MethodA<T, K>() where T:ClassA<K>, new()
{
  T<K> x=new T<K>();
}

or specify the predefined value for ClassA generic argument:

public void MethodA<T>() where T:ClassA<string>, new()
{
  T<string> x=new T<string>();
}

You can't specify ClassA as base class, because actually there is no such comiled class. The system will have few different classes compiled for [every] different type K. (Actually not every, but that's details).

Since ClassA can be used only with parameter and if you don't know the type of it in advance, you must add another generic parameter to your method.

In some cases (from what i see it's not your case, but maybe you missed something again) it is really required to have some base class for all generic classes. in this case you can create it like this:

public class ClassABase
{ }

public abstract class ClassA<T> : CkassABase
{}

public void MethodA<T, K>() where T:ClassABase, new()
{
  T<string> x=new T<string>();
}
Sasha
  • 7,731
  • 4
  • 41
  • 72
  • I see where you are going with this and yes - there is amistake in my original post - I will correct it – DJL Feb 04 '14 at 10:43
  • Edited my answer according to your change. Now it should work as you expect. – Sasha Feb 04 '14 at 10:51
  • Unfortunately this doesn't quite work because I wanted the value of K in your example to be decided internally to MethodA. I could essentially ignore K and specify whatever I need but that would go back to the original issue you highlighted of having an unused type parameter – DJL Feb 04 '14 at 10:53
  • If you have so many specific requirements why don't you put them in the original question? We don't see your problem, so how can we help? Anyway my last code sample should allow you 'define K in the method'. – Sasha Feb 04 '14 at 11:02
  • My apologies, I thought I had stated that already. I haven't tried your example yet however I suspect T may cause a compile error because T is not generic – DJL Feb 04 '14 at 11:03
  • Indeed as suspected: The type parameter 'T' cannot be used with type arguments Although it could probably done with reflection... – DJL Feb 04 '14 at 11:20
0

To help you brainstorm for your solution:

public class ClassA<T>
{}
public class ClassB<T>:ClassA<T>
{}
...
public void MethodA<T1, T2>() where T1 : ClassA<T2>, new()
{
  ClassA<T2> x=new ClassA<T2>();
}
...
public void MethodB<T1>() 
{
  ClassA<T1> x = new ClassA<T1>();
}

MethodA<ClassB>();

It depends on your use case, which is not apparent from your question.

Bas
  • 25,270
  • 7
  • 45
  • 82