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 }
- 参数类型’T’不能赋予参数类型’Orangutan’
- 参数类型’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
,所以你不能只将Orangutan
或IAnimal
分配给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); }