Alex Rivera | Logout

Generic method with Action<T> parameter

Asked 2009-11-24T18:48:13.847
9

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
}
  1. Argument type 'Orangutan' is not assignable to parameter type 'T'
  2. 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);
Edit
Report

1 Answer

7

Why are you instantiating an Orangutan if you are supposed to be accepting any IAnimal?

public void ValidateUsing<T>(Action<T> action) where T : IAnimal, new()
{
    T animal = new T();
    action(animal);  //Compile error 2

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 from IAnimal. However, it could just as easily be a Giraffe as an Orangutan, so you can't just assign an Orangutan or IAnimal to a parameter of type T.

answered 2009-11-24T18:59:49.797

Your Answer