So, I'm sure this has been answered somewhere out there before, but I couldn't find it anywhere. Hoping some generics guru can help.
public interface IAnimal{}
public class Orangutan:IAnimal{}
public void ValidateUsing<T>(Action<T> action) where T : IAnimal
{
Orangutan orangutan = new Orangutan();
action(orangutan); //Compile error 1
//This doesn't work either:
IAnimal animal = new Orangutan();
action(animal); //Compile error 2
}
- Argument type 'Orangutan' is not assignable to parameter type 'T'
- Argument type 'IAnimal' is not assignable to parameter type 'T'
Edit: Based on Yuriy and other's suggestions, I could do some casting such as:
public void ValidateUsing<T>(Action<T> action) where T : IAnimal
{
Orangutan orangutan = new Orangutan();
action((T)(IAnimal)orangutan);
//This doesn't work either:
IAnimal animal = new Orangutan();
action((T)animal);
}
The thing I wanted to do was call the ValidateUsing method like this:
ValidateUsing(Foo);
Unfortunately, if foo looks like this:
private void Foo(Orangutan obj)
{
//Do something
}
I have to explicitly specify the type when I call ValidateUsing
ValidateUsing<Orangutan>(Foo);
It also seems like the fact that it's an interface makes a difference. If you had an abstract class Animal, instead of an interface, you could do this:
Try this.
Why are you instantiating an
Orangutan
if you are supposed to be accepting anyIAnimal
?If you reuse your generic parameter, you won't have any type issues...
Now, with regard to why your code doesn't work, all that you're saying is that the type
T
will derive fromIAnimal
. However, it could just as easily be aGiraffe
as anOrangutan
, so you can't just assign anOrangutan
orIAnimal
to a parameter of typeT
.The thing is, that T represents some type which by the way implements IAnimal.
So, when you try to compile
action(new Organatum())
you getting an error because you have declared that the action should take a parameter of typeT
which in its turn could be of type, let's say,Fish
- you can't castOrganatum
to aFish
, can you?If you want to trigger any action which takes parameter of a type which implements
IAnimal
interface, then simply forget about generics and useAction<IAnimal>
.HTH.
Make the following changes: