我具有以下要使用MEF导出和导出的类接口模式:
public interface IDinosaur
{
string Species { get; }
}
public class Pterodactyl : IDinosaur
{
public string Species { get; set; }
public float WingSpan { get; set; }
}
public interface ICage<in T>
{
void Transport(T animal);
}
[Export(typeof(ICage<IDinosaur>))] // <-- This appears a problem
public class PterodactylCage : ICage<Pterodactyl>
{
public void Transport(Pterodactyl dinosaur) { }
}
public class DinoTransportationService
{
[Import(AllowDefault = true)]
private ICage<IDinosaur> m_dinosaurCage = null;
}
现在我要说这是合法的,因为
[Export(typeof(ICage<IDinosaur>))]
确实输出了ICage
的IDinosaur
(碰巧是Pterodactyl
,但这实现了恐龙接口,所以应该没事吧?)。但是,这给了我CompositionException。说:"The export 'PterodactylCage (ContractName=\"ICage(IDinosaur)\")' is not assignable to type 'ICage`1[[IDinosaur, MyProgramme, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'."
我可以通过将导出更改为:
[Export(typeof(ICage<Pterodactyl>))] // <-- This is ok
public class PterodactylCage : ICage<Pterodactyl>
并导入到:
[Import(AllowDefault = true)]
private ICage<Pterodactyl> m_dinosaurCage = null;
除此之外,现在的导入变得太具体了,实际上,就我而言,导入是在另一个从未听说过翼手龙的程序集中进行的,因此这是一个不好的解决方案。
为什么第一个示例不合法,该模式的解决方案是什么?
最佳答案
这是无效的,因为PterodactylCage
的实例(如错误消息所述)不能分配给ICage<IDinosaur>
:
ICage<IDinosaur> cage = new PterodactylCage(); // this won't compile
这与通用接口的协方差\协方差有关,您可以在Internet上的许多地方阅读它的内容(此处将描述广泛的主题)。
如果您具有以下接口定义:
public interface ICage<out T> // note "out" keyword
那将是合法的。但是,您不能在
Trasport
方法中使用out参数作为参数,因此不会解决您的问题。进一步了解为什么这在直观上是非法的。假设这是合法的。然后,您将使用具有
ICage<IDinosaur>
方法的Tranport
实例,该实例接受IDinosaur
。但是基础类型是PterodactylCage
,即ICage<Pterodactyl>
。但是您可以将IDinosaur
的任何实例传递给Transport
方法,而不仅是Pterodactyl
(记住-我们使用ICage<IDinosaur>
),这样会使我们产生矛盾。这就是为什么从直觉上讲这是不合法的。关于c# - 为什么以下带有接口(interface)的导入/导出模式不合法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37724942/