为什么以下具有接口的导入/导出模式不合法?

时间:2016-06-09 11:39:35

标签: c# interface mef

我有以下类接口模式,我想在其上使用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>

除此之外,导入现在变得太具体了,事实上,在我的情况下,导入是在一个从未听说过翼手龙的不同集合中,所以这是一个糟糕的解决方案。 为什么第一个例子不合法,这个模式的解决方案是什么?

1 个答案:

答案 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>),这样就会导致我们发生矛盾。这就是直觉上它不合法的原因。