我创建了一个具有子类的程序集,该子类派生自另一个程序集中定义的父类。
当我添加对子项的引用时,Visula 工作室还要求将引用添加到父项。
为什么会这样,我怎样才能在不丢失任何功能的情况下防止它?
我创建了一个具有子类的程序集,该子类派生自另一个程序集中定义的父类。
当我添加对子项的引用时,Visula 工作室还要求将引用添加到父项。
为什么会这样,我怎样才能在不丢失任何功能的情况下防止它?
你所描述的部分是可能的。您可以消除他们显式引用隐藏程序集的需要,但该程序集仍将在编译时被拉入,并在运行时需要。
假设您定义了这些类:
// 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,它具有 A 类型的局部变量。您实际上可以自由使用 D.Bar()即使程序集 1 在运行时完全丢失。虽然如果你调用 D.Foo() 并且缺少程序集 1,你会得到一个异常。
在 C/C++ 中,类定义存在于 .h 头文件中。这使您能够引用有关类的信息(根据需要,例如,当您想从该类继承时),而无需使用具有实现信息的源文件。缺点是代码重复(.cpp 文件中的实现需要重复 .h 文件中的大部分信息)。
在.NET 世界中,设计是不同的:程序集既包含类的代码(CLR 字节码),也包含从该类继承所需的所有元数据(类名、有关其成员的信息等)。
这种设计的结果是,为了使用在程序集 A 中定义的类继承自程序集 B 中的类,.NET 需要 A 和 B 程序集。或者更一般地说:如果您直接或间接使用给定程序集(类、枚举、结构)中的任何内容,则需要引用该程序集。
我不确定你想阻止什么。如果您决定像您描述的那样将代码拆分为两个程序集,那么就没有办法避免同时引用它们。
当然,有不同的方式来构建代码,但不知道通过首先将代码拆分为 2 个程序集来达到什么目标,因此不可能提出有用的建议。