我有一个通用接口,该接口具有接口约束,这是由于 我无法像我想要的那样协变。并且必须依靠动态。理想情况下,我想摆脱这一点,但找不到解决办法。
我们可以认为此问题类似于WebApi控制器。 我将有一个字符串和有效载荷一起输入。根据字符串名称,我需要选择适当的“策略”(控制器/方法)来运行并传递有效负载。
我也希望它能够自动工作,这意味着:我有一些“反射”代码,用于查找所有使用IAnimalAction <>的类,将它们加载到集合中,并设置DI容器。所有这些都能正常工作。
正如您在代码中看到的那样,动态效果完美,但是我想避免运行时异常,并在构建时将其包含。
public interface IAnimalType
{ }
public class Cat : IAnimalType
{ public string Name;}
public class Dog : IAnimalType
{ public int EvilFactor;}
public class Cow : IAnimalType
{ }
public interface IAnimalAction<T> where T : IAnimalType
{
bool ActUpon(T input);
}
public class IgnoreAnimal: IAnimalAction<Cat>
{
public bool ActUpon(Cat input)
{
return true;
}
}
public class LoveAnimal: IAnimalAction<Dog>, IAnimalAction<Cow>
{
public bool ActUpon(Dog input)
{
return true;
}
public bool ActUpon(Cow input)
{
return true;
}
}
public class test
{
public test()
{
var cat = new Cat();
var ignoreAction= SomeStaticInstance.GetRelevantAction(cat. GetType().Name);// returns new IgnoreAnimal(); in this case
var works = ((IAnimalAction<Cat>)ignoreAction).ActUpon(cat);
var alsoWorks= ((dynamic)ignoreAction).ActUpon(cat);
var doesnt= ((IAnimalAction<IAnimalType>)ignoreAction).ActUpon(constraint);
}
}
我希望能够确保方法'ActUpon'在我的实例上始终可用。
我了解协方差和逆方差的问题,但我认为必须有其他不依赖动态的方法。
由于我通过反射加载了我的类,并且仅加载了实现“接口IAnimalAction”的类,因此我认为它可以安全地保留,可以选择在接口中查找方法名称并让代码调用已解析的方法名,而不是硬编码“ ActUpon”。
将示例更新为少一些抽象