Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method with Action<T> parameter

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);
like image 701
Matt Hornsby Avatar asked Nov 24 '09 18:11

Matt Hornsby


People also ask

What is T on parameter C#?

In C#, the “T” parameter is often used to define functions that take any kind of type. They're used to write generic classes and methods that can work with any kind of data, while still maintaining strict type safety.

What is generic type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.

How do you invoke a generic method?

To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.

What is the correct way of defining a generic method?

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.


2 Answers

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.

like image 100
bdukes Avatar answered Oct 13 '22 06:10

bdukes


Make the following changes:

Orangutan orangutan = new Orangutan();
action((T)(IAnimal)orangutan); 


IAnimal animal = new Orangutan();
action((T)animal); 
like image 44
Yuriy Faktorovich Avatar answered Oct 13 '22 05:10

Yuriy Faktorovich