class GenericWrapper<T>
{
}
class WrapperInstance : GenericWrapper<string>
{
}
class Usage
{
public static Usage Create<T1, T2> (T2 t2) where T1 : GenericWrapper<T2>
{
return null;
}
}
...
// works
Usage.Create<WrapperInstance, string>("bar");
// doesnt work
Usage.Create<WrapperInstance>("bar");
I suspect the answer is no, but is there a way I can make the last line compile?
I want the compiler to force me to provide a string argument without having to know or first go and examine WrapperInstance to see what T of GenericWrapper it implements.
I know I can make it compile by either using the first method or by taking object as the argument and doing runtime checking, but thats not the question ;) I largely suspect these are my only two options.
Thanks
I suspect the answer is no, but is there a way I can make the last line compile?
No. Create has two generic type parameters. You either specify none or you specify both. In the case of none, the compiler will try to infer the types from the invocation arguments. However, in this case it can not because T1 never appears in the argument list. Therefore you must specify both.
There are two problems here:
You want to infer just one type argument, and specify the other. You can't do that with normal type inference. However, you could make Usage generic, thus specifying one type argument there, and letting the other be inferred using the generic method:
Usage<WrapperInstance>.Create("foo");
That's something I've often done before, but that just leads to the second problem...
Usage<WrapperInstance> doesn't "have" a T2 to validate... and you can't constrain an existing type parameter on a generic method - only ones which are introduced in the method.There's one way I think we could do this:
public class Usage
{
public static Usage<T2> For<T2>(T2 t2)
{
return new Usage<T2>(t2);
}
}
public class Usage<T2>
{
private readonly T2 t2; // Assuming we need it
public Usage(T2 t2)
{
this.t2 = t2;
}
// I don't know what return type you really want here
public static Foo Create<T1>() where T1 : GenericWrapper<T2>
{
// Whatever
}
}
You'd use it like this:
Usage.Foo("bar").Create<WrapperInstance>();
Without knowing more about what you're trying to do, I don't know whether or not that's helpful - but it does manage to accomplish what you were after in terms of:
WrapperInstance type argumentstring type argumentIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With