我有以下类接口模式,我想在其上使用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
的{{1}}(恰好是IDinosaur
,但这实现了恐龙接口应该没问题吧?)。但是,这给了我一个CompositionException。话说:
Pterodactyl
我可以通过将导出更改为:
来解决此问题"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>
除此之外,导入现在变得太具体了,事实上,在我的情况下,导入是在一个从未听说过翼手龙的不同集合中,所以这是一个糟糕的解决方案。 为什么第一个例子不合法,这个模式的解决方案是什么?
答案 0 :(得分:2)
这是无效的,因为(正如错误消息所说的那样)PterodactylCage
的实例不能分配给ICage<IDinosaur>
:
ICage<IDinosaur> cage = new PterodactylCage(); // this won't compile
这与通用接口的协方差或逆变有关,您可以通过互联网阅读它在很多地方的内容(这里有一个广泛的主题)。
如果你有这个界面定义:
public interface ICage<out T> // note "out" keyword
那么那将是合法的。但是,您不能在Trasport
方法中将参数用作参数,因此无法解决您的问题。
更直接地说明为什么这是非法的。假设它是合法的。然后,您拥有ICage<IDinosaur>
实例,其Tranport
方法接受IDinosaur
。但基础类型为PterodactylCage
,即ICage<Pterodactyl>
。但是您可以将IDinosaur
的任何实例传递给Transport
方法,而不只是Pterodactyl
(请记住 - 我们使用ICage<IDinosaur>
),这样就会导致我们发生矛盾。这就是直觉上它不合法的原因。