我遇到了一个我刚刚注意到的奇怪问题。
如果您有一个包含 3 个项目的解决方案
** 注意经讨论后编辑 **
LibA 项目 - 具有 A 类
namespace LibA
{
public class ClassA
{
public override string ToString()
{
return "The logic in class A!";
}
}
}
Project LibB - 有一个 ClassB
using LibA;
namespace LibB
{
public class ClassB
{
public ClassA a;
public ClassB()
{
a = new ClassA();
}
public object Foo()
{
return a;
}
}
}
LibC 项目 - 有一个 ClassC
using LibB;
namespace LibC
{
public class ClassC
{
public ClassB b;
public ClassC()
{
b = new ClassB();
}
public object Foo()
{
return b.Foo();
}
}
}
终于有试驾了
using System;
using LibC;
namespace Shell
{
class Program
{
static void Main(string[] args)
{
ClassC c = new ClassC();
Console.WriteLine(c.Foo());
}
}
}
现在如果你编译它,一切都会完美地工作。如果您检查 LibC 的二进制文件夹的内容,您会看到它自动遍历依赖链以确定它需要引入 LibA 和 LibB
但是,如果您将 ClassB 更改为继承自类 A 比如
using LibA;
namespace LibB
{
public class ClassB : ClassA
{
ClassA a;
}
}
尝试编译,会报错
Error 2 The type 'LibA.ClassA' is defined in an assembly that is not referenced. You must add a reference to assembly 'LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
** 原始问题 **
有谁知道为什么(无论是 msbuild 还是 visual studio)当 ClassA 是 ClassB 的成员时引用 LibA 足够聪明,但当 ClassA 是 ClassB 的基类时引用 LibA 就不够聪明?
我知道这很挑剔,但我真的很感激一些一致的行为
** 使用这些观察到的测试修改问题 **
我听说有人将其定义为“直接”或“间接”引用。然而,直接显然不仅仅是可见性范围,它似乎是一种类型的继承和实际使用。
没有继承,测试驱动程序足够智能,可以解析并自动引用 LibA、LibB 和 LibC。
在 ClassB 中有一个可见的 public 成员 ClassA,但它本身不会产生编译/链接错误。
调试器肯定会从测试驱动程序中解析出 ClassA,因此它显然加载了正确的程序集。
考虑到所有这些。我现在得到了所有“直接”和“间接”的东西。
为什么链接器/编译器/IDE 至少不尝试在“直接”场景中自动引用引用库的依赖项?它显然足够聪明,知道存在依赖关系并在“间接”场景中引用它们。
最佳答案
这是一致的行为。第一个是简单引用,第二个是继承。
如果一个程序集被编译并且一个类继承自另一个程序集中的类,则需要该引用来构造它。
LibB
只包含 ClassB
的类定义中添加的信息,它不会从 LibA 复制所有内容
(如果更新了 LibA
并更改了 ClassA
,这将产生不一致的代码,LibB
仍将包含旧信息).
因此,要在 LibC
中使用继承的类定义,它需要来自 LibA
(对于 ClassA
)和 LibB 的信息
(ClassB
) 来构造它,因此需要直接引用 LibA
。
在这个例子中,所有对不同程序集的类的引用都是私有(private)的,因此只需要下一层(ClassC
不需要知道 ClassA
因为那里没有直接使用该类)。如果在 ClassB
中使用 ClassA
是公共(public)字段或属性,则 ClassC
将直接引用 ClassA
并且还需要对该类定义的直接引用(从 LibC
引用 LibA
)。
换一种形式,在继承的例子中也是如此。 ClassC
直接引用了 ClassA
(由于 ClassB
继承自 ClassA
),因此引用了声明构建完整的类定义需要程序集(即 LibA
)。
关于c# - .Net 继承 - 自动依赖引用行为问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4445213/