I have a situation where I have a class that accepts an instance of a certain object type in its generic type parameter. The layout is something like this:
public abstract BaseClass { ... }
public DiamondClass : BaseClass { ... }
public SilverClass : BaseClass { ... }
public Handler<T> where T : BaseClass { ... }
I want to be able to create a method to return an instance of Handler<DiamondClass>
or Handler<BaseClass>
without defining the type upon input. I've tried something along these lines:
public Handler<BaseClass> GetHandler(HandlerType type)
{
switch(type)
{
case HandlerType.Diamond: return new Handler<DiamondClass>();
case HandlerType.Silver: return new Handler<SilverClass>();
default: throw new InvalidOperationException("...");
}
}
But this won't work, because apparently Handler<DiamondClass>
won't cast implicitly to Handler<BaseClass>
. I can specify it like this:
public Handler<T> GetHandler<T>(HandlerType type) where T : BaseClass
{
switch(type)
{
case HandlerType.Diamond: return (Handler<T>)new Handler<DiamondClass>();
case HandlerType.Silver: return (Handler<T>)new Handler<SilverClass>();
default: throw new InvalidOperationException("...");
}
}
But now I need to call GetHandler<DiamondClass>
or GetHandler<BaseClass>
. And that defeats the purpose of having a method that returns the proper handler based on an enum, without knowing the type. I hoped that I could define a Type
object and pass it, as such:
Type objType = typeof(DiamondClass);
var handler = Handler<objType>();
But apparently C# won't allow that kind of foolishness. I've gone about this several different ways, and I'd like to think there's a way to do it, but I'm stumped.
(I actually did get this working by returning a dynamic
object, but I'd like to avoid it if at all possible, as it loses any type safety and Intellisense support.)
To examine a generic type and its type parametersGet an instance of Type that represents the generic type. In the following code, the type is obtained using the C# typeof operator ( GetType in Visual Basic, typeid in Visual C++). See the Type class topic for other ways to get a Type object.
An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.
Yes, you can define a generic method in a non-generic class in Java.
So, to return a null or default value from a generic method we can make use default(). default(T) will return the default object of the type which is provided.
This is where co-variance comes into play, covariance and contra-variance just work only on interface and delegate, so, to solve your problem, just define a new interface IHandler
as co-variant with out
which specifies that the type parameter is co-variant:
public interface IHandler<out T> where T : BaseClass
{
}
An interface that has a covariant type parameter enables its methods to return more derived types than those specified by the type parameter
It will work. More information is here
If 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