Action 参数的通用方法

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

public interface IAnimal{} public class Orangutan:IAnimal{} public void ValidateUsing(Action 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. 参数类型’T’不能赋予参数类型’Orangutan’
  2. 参数类型’IAnimal’不能分配给参数类型’T’

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

 public void ValidateUsing(Action action) where T : IAnimal { Orangutan orangutan = new Orangutan(); action((T)(IAnimal)orangutan); //This doesn't work either: IAnimal animal = new Orangutan(); action((T)animal); } 

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

 ValidateUsing(Foo); 

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

 private void Foo(Orangutan obj) { //Do something } 

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

 ValidateUsing(Foo); 

如果您应该接受任何IAnimal为什么要实例化Orangutan呢?

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

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

现在,关于为什么你的代码不起作用,你所说的只是类型T将从IAnimal派生。 然而,它可以像长IAnimal一样容易成为Giraffe ,所以你不能只将OrangutanIAnimal分配给T型参数。

问题是,T表示某种类型,它通过实现IAnimal的方式。

所以,当你尝试编译action(new Organatum())你得到一个错误,因为你已经声明该动作应该采用类型为T的参数,而这个参数又可以是类型,比方说, Fish – 你不能把Organatum一条Fish ,可以吗?

如果要触发任何采用实现IAnimal接口的类型参数的操作,那么只需忘记generics并使用Action

HTH。

进行以下更改:

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

试试这个。

 Orangutan orangutan = new Orangutan(); Action castedAction = action as Action; castedAction(orangutan); 
 public interface IAnimal { } public class Orangutan : IAnimal { } public void ValidateUsing(Action action) where T : IAnimal { Orangutan orangutan = new Orangutan(); action((T)(orangutan as IAnimal)); // needs to be cast as IAnimal //This doesn't work either: IAnimal animal = new Orangutan(); action((T)animal); // needs to be cast as T } 

它似乎也是一个事实,它是一个界面有所作为。 如果你有一个抽象类Animal,而不是一个接口,你可以这样做:

 public abstract class Animal { } public class Orangutan : Animal { } public void ValidateUsing(Action action) where T : Animal { Orangutan orangutan = new Orangutan(); action(orangutan as T); //This doesn't work either: Animal animal = new Orangutan(); action(animal as T); }