【发布时间】:2011-05-25 14:49:54
【问题描述】:
我遇到了一个我刚刚注意到的奇怪问题。
如果您有 3 个项目的解决方案
** 注意讨论后编辑**
项目 LibA - 有一个 ClassA
namespace LibA
{
public class ClassA
{
public override string ToString()
{
return "The logic in class A!";
}
}
}
项目 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;
}
}
尝试编译,会报错
错误 2 类型“LibA.ClassA”在未引用的程序集中定义。您必须添加对程序集“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 至少不尝试在“直接”场景中自动引用被引用库的依赖项,仍然没有点击我的东西?知道存在依赖关系并在“间接”场景中引用它们显然足够聪明。
【问题讨论】:
-
绝对有趣。作为前 VB.NET 的人,这是我无法理解的。 VB.NET 编译器足够智能,可以链接项目依赖项;为什么没有 C# 编译器?
标签: c# inheritance reference dependencies