添加装配参考也需要引用基础装配

时间:2010-04-06 19:55:10

标签: .net assemblies assembly-resolution

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

当我添加对孩子的引用时,Visula studio还需要将引用添加到父级。

为什么会这样,如何在不丢失任何功能的情况下阻止它?

2 个答案:

答案 0 :(得分:2)

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

假设您已定义了这些类:

// 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.有3个不同的公共引用A,其中任何一个都需要知道A才能使用B.

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

如果最终用户使用D类,而不使用B或C,则只有在调用具有A类局部变量的D.Foo()时才会加载程序集1.您实际上可以使用D.Bar ()即使组件1在运行时完全丢失也是自由的。虽然如果你调用D.Foo()并且缺少程序集1,你会得到一个例外。

答案 1 :(得分:0)

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

在.NET世界中,设计是不同的:程序集包含类的代码(CLR字节码)以及例如所需的所有元数据(类名,有关其成员的信息等)。继承自那个班级。

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

我不确定你想要阻止什么。如果您决定将代码拆分为两个如您所述的程序集,则无需引用它们。

当然,有不同的方法来构造你的代码,但不知道你试图通过将代码分成2个程序集来实现的目标,这是不可能提出有用的建议。