c# - .Net 继承 - 自动依赖引用行为问题

标签 c# inheritance reference dependencies

我遇到了一个我刚刚注意到的奇怪问题。

如果您有一个包含 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/

相关文章:

c# - 返回空任务还是返回 null 更好? C#

c++ - 为什么我在使用 memset 用零填充对象后在 dynamic_cast 处出现异常

java - List<Dog> 是 List<Animal> 的子类吗?为什么 Java 泛型不是隐式多态的?

javascript - 如何使用 Object.create 在 javascript 中继承私有(private)变量

c++ - 引用指针(int * const和arg)

c# - 具有多泛型问题的 AppDomain.DoCallBack()

c# - Azure 服务启动日志

excel - 在 Excel 2007 中进行双单元格引用

c# - 通知 View 模型模型已更改(来自组合框)

c# - 找不到命名空间名称的类型(是否缺少 using 指令或程序集引用?)