自动依赖引用行为问题

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

如果您有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,版本= 1.0.0.0,Culture = neutral,PublicKeyToken = null'的引用。

**原始问题**

有人知道为什么(无论是msbuild还是visual studio),当ClassA是ClassB的成员时,它足够聪明地引用LibA,但是当ClassA是ClassB的基类时,它不够聪明以引用LibA?

我知道这很挑剔,但我真的很感激一些一贯的行为

**修正后的问题与这些观察到的测试**

我听到有人将其定义为“直接”或“间接”引用。 然而,直接显然不仅仅是可见性范围,它似乎是一种类型的继承和实际使用。

如果没有继承,测试驱动程序足够聪明,可以解析并自动引用LibA,LibB和LibC。

在ClassB中有一个公共成员ClassA,但单独不会产生编译/链接错误。

调试器明确地解析了测试驱动程序中的ClassA,因此它清楚地加载了正确的程序集。

所有这一切都铭记在心。 现在我得到了整个“直接”和“间接”的东西。

这仍然没有点击我为什么链接器/编译器/ IDE至少不会尝试在“直接”场景中自动引用引用库的依赖关系? 它明显足够聪明,可以知道依赖关系在那里,并在“间接”的情况下引用它们。


这是一致的行为。 第一个是简单的参考,第二个是继承。

如果一个程序集被编译并且一个类从另一个程序集中的类继承,则需要该引用来构造它。

LibB只包含在ClassB的类定义中添加的信息,它不会复制LibA所有LibA (如果LibA更新并且ClassA在更改时会产生不一致的代码, LibB仍会包含旧信息)。

因此,要在LibC使用继承的类定义,它需要来自LibA (用于ClassA )和LibBClassB )的信息来构造它,因此需要直接引用LibA

在这个例子中,所有对不同程序集类的引用都是私有的,因此只有下一个层次是需要的( ClassC不需要了解ClassA因为没有直接使用该类)。 如果ClassB中的ClassA的使用是公共领域或ClassCClassC将直接引用ClassA并且还需要对该类定义的直接引用(从LibC引用LibA )。

在另一种形式中,继承示例中也是这种情况。 ClassC直接引用ClassA (由于ClassBClassA ),因此需要引用声明程序集(即LibA )来构造完整的类定义。


我知道这很挑剔,但我真的很感激一些一贯的行为

它是一致的。 您必须引用您直接使用的任何类型。 间接引用是透明解析的。


在第一种情况下,您只是使用ClassA 。 所以,它不需要编译时的资源,只是在运行时。

在第二种情况下,您是从ClassA继承的 ,因此编译器需要它的定义和信息才能构建最终的程序集。

在第一种情况下,VisualStudio 将引用的DLL复制到输出目录中 ,因为它知道你需要它。

在第二种情况下,VisualStudio不会将引用添加到项目中 ,这是我假设的,您的主要疑问。 我想这是为了通过侵入你的项目来避免问题。 但是,我只是猜测...

链接地址: http://www.djcxy.com/p/49421.html

上一篇: Automatic dependency referencing behavior issue

下一篇: Ruby game frameworks that are still actively maintained?