为什么我需要引用一个我没有直接使用的dll?

Neo*_*ard 8 c# inheritance reference

我有从外部开发人员那里收到的源代码,这个代码分为4种类型的项目:他们的框架,我的项目的环境(让我们称之为"ENV"),应用程序库(称之为"Base")和应用程序本身(约20个dll我将统称为"App").

现在,我已经为这个混乱添加了另一层,一个名为AdvanceFeatures的dll.它位于ENV(框架顶部)的正下方.这个dll只引用框架,ENV引用它.只有ENV使用这个AdvanceFeatures dll,而Base和App只使用ENV.

我在这里工作的方式是App中的大多数对象都在Base中定义,并在ENV中继承/实现类/接口.这些对象中的一小部分(在App和Base中)从框架本身继承/实现类/接口(但这种情况非常罕见).

除了一个事实,到目前为止一切都很顺利.编译器要求我将从App中的每个dll和Base中添加对AdvanceFeatures dll的引用.

我没有在ENV之外使用AdvanceFeatures,那么为什么需要这些引用呢?

编辑:我已经为这个问题创建了一个演示项目.这是项目细节:

Assembly: AdvanceFeatures
References: Nothing (Reference project-folder is empty)
Classes: Decorator, IEnvClass, IDecorator
IDecorator contents:
namespace AdvanceFeatures
{
    public interface IDecorator
    {
        IEnvClass Decorated { get; }
        void Decorate();
    }
}

IEnvClass contents: 
namespace AdvanceFeatures
{
    public interface IEnvClass
    {
        string Name { get; set; }
    }
}

Decorator contents:
namespace AdvanceFeatures
{
    public class Decorator : IDecorator
    {

        public Decorator(IEnvClass decorated)
        {
            Decorated = decorated;
        }

        #region Implementation of IDecorator

        public IEnvClass Decorated { get; set; }

        public void Decorate()
        {
            Decorated.Name = "NewName";
        }   

        #endregion
    }
}

Assembly: ENV
References: AdvanceFeatures (Compiled DLL)
Contents of only class SomeEnvClass:

namespace ENV
{
    public class SomeEnvClass : AdvanceFeatures.IEnvClass
    {
        public string Name { get; set; }
        private readonly AdvanceFeatures.IDecorator _decorator;

        public SomeEnvClass(string name)
        {
            Name = name;
            _decorator = new AdvanceFeatures.Decorator(this);
            _decorator.Decorate();
        }

        public string Foo()
        {
            return Name;
        }
    }
}


Assembly: TestBase
References: ENV (compiled DLL)
Contents of only class SomeEnvExtendingClass:

namespace TestBase
{
    public class SomeEnvExtandingClass : ENV.SomeEnvClass
    {
        public SomeEnvExtandingClass(string name) : base(name)
        {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:

错误1"AdvanceFeatures.IEnvClass"类型在未引用的程序集中定义.您必须添加对程序集'AdvanceFeatures,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'的引用.E:\ Projects\Dev\TestReferenceInheritance\TestBase\SomeEnvExtandingClass.cs 3 18 TestBase

现在,我知道为什么DLL必须可用于编译的可执行文件,但为什么开发人员应该知道ENV的内部工作方式(更具体地说,它是继承树)以扩展它?

Dav*_*son 10

我阅读了所有的答案和评论,所以我想出了这个例子.也许它更容易理解.:)

Interfaces.dll

public interface DoesntAcceptValidAndAccurateAnswersOrComments {
    bool ImAlwaysRight();
}
Run Code Online (Sandbox Code Playgroud)

Classes.dll - 引用Interfaces.dll

public class Neowizard : Interfaces.DoesntAcceptValidAndAccurateAnswersOrComments {
    public bool ImAlwaysRight() {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Program.exe - 引用Classes.dll

public class StackOverflowDotCom {
    public static void Main() {
        Neowizard someGuy = new Neowizard(); // CS0012
        someGuy.ImAlwaysRight();
    }
}
Run Code Online (Sandbox Code Playgroud)

这与编译器有关.当它尝试编译Program.exe时,它会看到一个Neowizard类型的对象.它还看到它实现了一些名为DoesntAcceptValidAndAccurateAnswersOrComments的接口,但是没有对Interfaces.dll的引用它找不到它,因此它无法编译,因为它是一个接口,就编译器而言,不存在于Program中.可执行程序.

因为Program.exe使用Neowizard,它还必须使用Neowizard派生的任何东西,它恰好是接口.这不仅适用于接口,而且与封装无关.这是C#编程语言的一个规则,由编译器强制执行.

如果你想更多地论证这个案子,那么你应该去问一下C#编译器团队中的某个人更多关于它的问题,但是当他们的答案实际上非常准确并且受过良好教育时,请放弃试图帮助你解决问题的每个人的答案. .


For*_*say 1

本质上有两种可能性:

  1. 您可能会在没有意识到的情况下使用 AdvanceFeatures 库的一部分,例如在某些时候获取对继承自 AdvanceFeatures 中的类的类的引用。这个类可能很小,您可能在 AdvanceFeatures 中有一个枚举,例如,它由 ENV 中的方法返回。
  2. 你还没有做过这样的事情,但事实是图书馆仍然需要在那里。除非您将 AdvanceFeature dll 嵌入到 ENV 中,否则如果没有 AdvanceFeature 在某处,您实际上将无法使用 ENV。通常这仅意味着它需要与可执行文件位于同一文件夹中。可能值得检查您是否将库设置为在其属性中复制本地等,或者对其属性的引用。