具有Action <T>参数的通用方法

Mat*_*sby 8 c# generics delegates

所以,我确信之前已在某处回答过,但我无法在任何地方找到它.希望一些仿制药大师可以提供帮助.

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
}
Run Code Online (Sandbox Code Playgroud)
  1. 参数类型'T'不能赋予参数类型'Orangutan'
  2. 参数类型'IAnimal'不能分配给参数类型'T'

编辑:基于Yuriy和其他人的建议,我可以做一些演员,如:

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);
}
Run Code Online (Sandbox Code Playgroud)

我想要做的是调用ValidateUsing方法,如下所示:

ValidateUsing(Foo);  
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果foo看起来像这样:

private void Foo(Orangutan obj)
{
    //Do something
}
Run Code Online (Sandbox Code Playgroud)

我在调用ValidateUsing时必须明确指定类型

ValidateUsing<Orangutan>(Foo);
Run Code Online (Sandbox Code Playgroud)

bdu*_*kes 6

Orangutan如果你应该接受任何一个,你为什么要实例化IAnimal

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

如果您重用通用参数,则不会出现任何类型问题......

现在,关于为什么你的代码不起作用,你所说的只是类型T将来自IAnimal.但是,它可以很容易地Giraffe成为一个Orangutan,所以你不能只指定一个OrangutanIAnimal一个类型的参数T.