为什么会得到:在未引用的程序集中定义了“ IThirdParty”类型。您必须添加对程序集“ ThirdPartyAssembly”的引用吗?

时间:2019-06-24 02:22:00

标签: c# assembly-references interface-implementation

假设有第三方程序集ThirdPartyAssembly.dll公开了以下内容:

namespace ThirdPartyAssembly
{
    public interface IThirdParty
    {
        void GetInstance(ThirdPartyInfo info);
    }

    public class ThirdPartyInfo
    {
        public ThirdPartyInfo(string instanceText);
        public string InstanceText { get; set; }
    }
}

在解决方案的一个项目MyAssembly中,我引用ThirdPartyAssembly.dll并实现以下代码:

namespace MyAssembly
{
    public abstract class AbstractMyClass1 : IThirdParty
    {
        void IThirdParty.GetInstance(ThirdPartyInfo info)
        {
            info.InstanceText = "some-text";
        }
    }

    public abstract class AbstractMyClass1Consumer<T>
        where T : AbstractMyClass1
    {
    }
}

在第二个解决方案项目MyAssemblyConsumer中,我引用MyAssembly(作为解决方案项目参考)并实现以下分类

namespace MyAssemblyConsumer
{
    class MyClass1 : AbstractMyClass1
    {
    }

    class MyClass1Consumer : AbstractMyClass1Consumer<MyClass1>
    {
    }
}

到目前为止,一切都可以编译。 但是,当我将IMyClass2添加到MyAssembly项目中时,该项目将继承以下抽象类的IThirdParty接口

namespace MyAssembly
{
    public interface IMyClass2 : IThirdParty
    {
    }

    public abstract class AbstractMyClass2 : IMyClass2
    {
        void IThirdParty.GetInstance(ThirdPartyInfo info)
        {
            info.InstanceText = "some-text";
        }
    }

    public abstract class AbstractMyClass2Consumer<T>
        where T : IMyClass2
    {
    }
}

并尝试将以下类实现为MyAssemblyConsumer

namespace MyAssemblyConsumer
{
    class MyClass2 : AbstractMyClass2
    {
    }
    class MyClass2Consumer : AbstractMyClass2Consumer<MyClass2>
    {
    }
}

我在MyClass2Consumer上遇到以下编译错误:

在未引用的程序集中定义了“ IThirdParty”类型。您必须添加对程序集“ ThirdPartyAssembly”的引用

为什么我不需要在第一种情况下引用ThirdParty.dll,而在第二种情况下需要此引用?

1 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为在第一种情况下,您“隐藏”了对ThirdPartyAssembly.dll的引用。是的,您的公共AbstractMyClass1从中实现了IThirdParty,但是它实现了implicitly,所以调用IThirdParty.GetInstance()方法的唯一方法是这样的:

var myClass1Instance = new MyClass1();
var info = new ThirdPartyInfo(); 

(myClass1Instance as IThirdParty).GetInstance(info); // this can be called
myClass1Instance.GetInstance(info); // <- this method doesn't exists

因此,在MyAssemblyConsumer项目的编译时,编译器不需要了解任何关于IThirdParty的信息。如您所说,您的第一种情况已成功编译,我想您没有这样的代码。

在第二种情况下,您通过公开的IThirdParty接口公开了ThirdPartyAssembly.dll中的IMyClass2。在这种情况下,编译器必须在编译时了解IThirdParty接口(在定义AbstractMyClass2Consumer<T>的那一行上),这就是为什么会出现此异常的原因。