Reputation: 3227
A colleague of mine posted a question on an internal forum which got me thinking about whether this was possible through C#. Basically, he's got an interface as follows:
public interface IProvider<T>
{
T GetT();
}
Is it possible to use something that implements that interface as a type parameter to another generic class and have access to the type T without re-specifying it? For example:
public class Foo<P> where P : IProvider<T>
{
P p;
T GetInnerT() { return p.GetT(); }
}
This does not compile, because the type T is not defined and hence can't be used as a parameter for IProvider
. Is something like this even possible? Just curious!
Upvotes: 1
Views: 121
Reputation: 34198
No, it's not possible, because your definition doesn't allow for the provision of type T
when declaring Foo
. Consider:
var x = new Foo<string>();
What is T
in this case? There is no way to know at compile-time nor at runtime.
As you yourself said: the type T
is not defined, and for the class to be valid you have to provide a means of definition. For example:
public class Foo<P, T> where P : IProvider<T>
Upvotes: 2
Reputation: 1500675
No, he'd need Foo
to be generic in both P and T:
public class Foo<P, T> where P : IProvider<T>
otherwise there's no T
for the IProvider<T>
constraint to be aware of - the fact that it's part of the declaration of IProvider<T>
is coincidental. The T
in the above declaration is entirely separate (from the compiler's point of view) from the T
in IProvider<T>
. For example, this would be an equivalent declaration:
public class Foo<TProvider, TProvided> where TProvider : IProvider<TProvided>
Another thing to bear in mind is that an implementation of IProvider<T>
could implement it multiple times, for different type arguments:
public class BigProvider : IProvider<string>, IProvider<int>, IProvider<char>
Now what would Foo<BigProvider>
mean? It would be ambiguous... whereas with my declaration above, you'd do:
var x = new Foo<BigProvider, int>();
to mean the int-providing aspect of BigProvider
.
Upvotes: 6