Is it possible to use generic parameter from another generic type, and infer the usage where used like this:
public class TypeA<T2> { }
public class TypeB<T1, T3, T2> where T3 : TypeA<T2> {}
public class Test
{
public Test()
{
// works but kind of ugly...
new TypeB<string, TypeA<int>, int>();
// Is it possible somehow to infer the TypeAType from the implemented generic generic type so I can use it like this?
new TypeB<string, TypeA<int>>();
}
}
CodePudding user response:
The short answer is no, because C# does not support "generics on generics".
To explain what that means let me show you are more concrete example:
List<int> list = new List<int>();
HashSet<int> set = list.To<HashSet<int>>();
Here, the extension method To()
is a magical piece of code that can convert one type of container into another.
Assuming C# supported this feature, one would naively try to define that method like so:
public static class EnumerableExtensions {
public static TContainer<TItem> To<TContainer<TItem>>(
this IEnumerable<TItem> source)
where TContainer: IEnumerable {
// magic
}
}
This of course won't compile, because C# cannot parse a generic type parameter that is generic itself (TContainer<TItem>
).
This whole concept is called higher kinded polymorphism (or higher kinded types) which C# doesn't support. It might in the future though and you can track progress in this GitHub issue.
There is a Nuget package called LanguageExt which provides some higher-kinded types and if I recall correctly it does the same thing you do: explicitly declare the inner type so the type inference can use it.
CodePudding user response:
You can get close by introducing another type, with the same name, but with fewer constraints. To use in this situation;
public class TypeB<T1, T3, T2> where T3 : TypeA<T2> {}
public class TypeB<T1, T2> : TypeB<T1, TypeA<T2>, T2> {}
new TypeB<string, int>();
See also UserStore<...>
from AspNetCore.Identity.