所以,我确信之前已在某处回答过,但我无法在任何地方找到它。希望一些仿制药专家可以提供帮助。
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
}
编辑:根据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);
}
我想要做的是调用ValidateUsing方法,如下所示:
ValidateUsing(Foo);
不幸的是,如果foo看起来像这样:
private void Foo(Orangutan obj)
{
//Do something
}
当我调用ValidateUsing
时,我必须明确指定类型ValidateUsing<Orangutan>(Foo);
答案 0 :(得分:6)
如果您应该接受任何Orangutan
,为什么要实例化IAnimal
?
public void ValidateUsing<T>(Action<T> action) where T : IAnimal, new()
{
T animal = new T();
action(animal); //Compile error 2
如果您重复使用通用参数,则不会出现任何类型问题......
现在,关于您的代码无效的原因,您所说的只是T
类型派生自IAnimal
。但是,Giraffe
与Orangutan
一样容易,因此您不能只将Orangutan
或IAnimal
分配给T
类型的参数}。
答案 1 :(得分:4)
问题是,T代表某种类型,它实现了IAnimal。
因此,当您尝试编译action(new Organatum())
时,您会收到错误,因为您已声明该操作应采用T
类型的参数,而该参数又可以是类型,例如,{ {1}} - 您无法将Fish
投射到Organatum
,是吗?
如果要触发任何采用实现Fish
接口的类型参数的操作,那么只需忘记泛型并使用IAnimal
。
HTH。
答案 2 :(得分:2)
试试这个。
Orangutan orangutan = new Orangutan();
Action<IAnimal> castedAction = action as Action<IAnimal>;
castedAction(orangutan);
答案 3 :(得分:2)
进行以下更改:
Orangutan orangutan = new Orangutan();
action((T)(IAnimal)orangutan);
IAnimal animal = new Orangutan();
action((T)animal);
答案 4 :(得分:0)
public interface IAnimal { }
public class Orangutan : IAnimal { }
public void ValidateUsing<T>(Action<T> 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<T>(Action<T> 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);
}