代码之家  ›  专栏  ›  技术社区  ›  Mrchief

添加程序集引用也需要引用基程序集

  •  2
  • Mrchief  · 技术社区  · 14 年前

    我创建了一个程序集,该程序集的子类派生自另一个程序集中定义的父类。

    当我向子对象添加引用时,Visula Studio还要求将引用添加到父对象。

    为什么是这样,我如何才能防止它失去任何功能?

    2 回复  |  直到 12 年前
        1
  •  0
  •   Krzysztof Kowalczyk    14 年前

    在C/C++中,类定义存在于.h头文件中。这使您能够引用有关类的信息(根据需要,例如当您希望从该类继承时),而无需使用实现信息来源文件。缺点是代码重复(在.cpp文件中的实现需要重复.h文件中的大部分信息)。

    在.NET世界中,设计是不同的:程序集既包含类的代码(CLR字节码),也包含从该类继承所需的所有元数据(类名、有关其成员的信息等)。

    这种设计的一个结果是,为了使用在程序集A中定义的、继承自程序集B中的类的类,.NET同时需要A和B程序集。或者更一般地说:如果直接或间接使用给定程序集(类、枚举、结构)中的任何内容,则需要引用该程序集。

    我不知道你想阻止什么。如果决定将代码拆分为两个程序集(如前所述),则无法避免同时引用这两个程序集。

    当然,有不同的方法来构造代码,但是不知道通过首先将代码分成两个程序集来实现什么目标,不可能提出有用的建议。

        2
  •  2
  •   Bryce Wagner    12 年前

    你所描述的部分是可能的。您可以消除它们显式引用隐藏程序集的需要,但该程序集仍将在编译时被拉入,并且在运行时是必需的。

    假设您定义了这些类:

    // in assembly 1:
    public class A
    {
        public virtual void Foo() { }
    }
    
    // and in assembly 2:
    
    // requires explicit reference to assembly 1 to use
    public class B : A
    {
        public override void Foo() { }
        public A Value { get; set; }
        public void Foo(A value) { }
    }
    // has implicit reference to assembly 1, but end user can ignore
    public class C
    {
        private A Value { get; set; }
        internal void Foo(A value) { }
        protected internal A Bar() { return new A(); }
    }
    // usable at runtime even if assembly 1 is missing, as long as you don't call Foo()
    public class D
    {
        public void Foo() { A blah = new A(); }
        public void Bar() { }
    }
    

    如果最终用户使用B类,则需要显式引用程序集1。由于a是b的公共接口的一部分,为了使用b,你必须了解a。a有3种不同的公共引用,其中任何一种都需要知道a才能使用b。

    但是,C类引用了A,但所有引用都是私有的/内部的/本地的。由于对a的每个引用都是从外部隐藏的,因此最终用户不必显式了解程序集1。它在运行时仍然是必需的,但您不必将其添加为引用,它是一个间接引用。

    如果最终用户使用类d,而不使用b或c,则只有调用d.foo()时才会加载程序集1,d.foo()具有类型a的局部变量。实际上,即使程序集1在运行时完全丢失,也可以自由使用d.bar()。尽管如果调用d.foo()并且缺少程序集1,但会出现异常。

    推荐文章