.Net Inheritance - 自动依赖引用行为问题

.Net Inheritance - Automatic dependency referencing behavior issue(.Net Inheritance - 自动依赖引用行为问题)
本文介绍了.Net Inheritance - 自动依赖引用行为问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've come across a strange issue that I've just now noticed.

如果您有 3 个项目的解决方案

If you have a solution with 3 projects

** 注意讨论后编辑**

** NOTE Edited after discussion **

项目 LibA - 有一个 ClassA

Project LibA - Has a ClassA

namespace LibA
{
    public class ClassA
    {
        public override string ToString()
        {
            return "The logic in class A!";
        }
    }
}

项目 LibB - 有一个 ClassB

Project LibB - Has a ClassB

using LibA;

namespace LibB
{
    public class ClassB
    {
        public ClassA a;

        public ClassB()
        {
            a = new ClassA();
        }

        public object Foo()
        {
            return a;
        }
    }
}

项目 LibC - 有一个 ClassC

Project LibC - Has a 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

Now if you compile this, everything will work perfectly. If you examine the contents of LibC's binary folder, you'll see that it automatically rolled through the chain of dependencies to determine that it needed to pull in LibA and LibB

但是,如果您将 ClassB 更改为从 A 类继承比如

However, if you alter ClassB to inherit from class A such as

using LibA;

namespace LibB
{
    public class ClassB : ClassA
    {
        ClassA a;
    }
}

尝试编译,会报错

错误 2 类型LibA.ClassA"在未引用的程序集中定义.您必须添加对程序集LibA,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"的引用.
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 不够聪明?

Does anyone know why (whether it is msbuild or visual studio) it is smart enough to reference LibA when ClassA a member of ClassB, but it isn't smart enough to reference LibA when ClassA is the base class of ClassB?

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

I know it's nitpicky, but I would really appreciate some consistent behavior

** 用这些观察到的测试修正了问题 **

** Amended Question with these observed tests **

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

I'm hearing what some define as "direct" or "indirect" references. However, direct is clearly not just the visibility scoping, it seems to be inheritance and actual usage of a type.

在没有继承的情况下,测试驱动程序足够聪明,可以解析并自动引用 LibA、LibB 和 LibC.

Without inheritance, the test driver is smart enough to resolve and automatically reference LibA, LibB and LibC.

在 ClassB 中有一个可见的 public 成员 ClassA,但仅此一项不会产生编译/链接错误.

There is a public member ClassA visible in ClassB and yet that alone doesn't produce the compilation/linking error.

调试器肯定会从测试驱动程序中解析 ClassA,因此它清楚地加载了正确的程序集.

The debugger definitely resolves ClassA from the test driver, so it clearly loaded the correct assembly.

所以考虑到所有这些.我现在得到了整个直接"和间接"的东西.

So with all that in mind. I get the whole "direct" and "indirect" stuff now.

为什么链接器/编译器/IDE 至少不尝试在直接"场景中自动引用被引用库的依赖项?知道存在依赖关系并在间接"场景中引用它们显然足够聪明.

The thing that is still not clicking to me why the linker/compiler/IDE doesn't at least try to automatically reference the dependencies of a referenced library in an "direct" scenario? It's clearly smart enough to know the dependencies are there and reference them in an "indirect" scenario.

推荐答案

这是一致的行为.第一个是简单的引用,第二个是继承.

This is consistent behaviour. The first one is a simple reference, the second one is inheritance.

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

If an assembly is compiled and a class inherits from a class in another assembly, that reference is required to construct it.

LibB 只包含ClassB 的类定义中添加 的信息,它不会从 LibA 中复制所有内容 (如果 LibA 被更新并且 ClassA 被改变,这将产生不一致的代码,LibB 仍然包含旧信息).

LibB only contains the information that is added in the class definition of ClassB, it doesn't copy everything from LibA (this would produce inconsistent code if LibA is updated and ClassA is changed while doing that, LibB would still contain the old information).

所以要在 LibC 中使用继承的类定义,它需要来自 LibA(对于 ClassA)和 LibB 的信息 (ClassB) 来构造它,因此需要直接引用 LibA.

So to use an inherited class definition in LibC, it needs both the information from LibA (for ClassA) and LibB (ClassB) to construct it, thus a direct reference to LibA is needed.

在示例中,对不同程序集的类的所有引用都是私有的,因此只需要下一级(ClassC 不需要知道 ClassA 在那里不是该类的直接用法).如果在 ClassB 中使用的 ClassA 是公共字段或属性,则 ClassC 将直接引用 ClassA并且还需要直接引用该类定义(从 LibC 引用 LibA).

In the example, all references to classes of different assemblies are private, thus only the next level is neeed (ClassC doesn't need to know about ClassA as there is no direct usage of that class). If the usage of ClassA in ClassB was a public field or propety, ClassC would have a direct reference to ClassA and would need a direct reference to that class definition as well (reference to LibA from LibC).

在不同的形式中,继承示例也是如此.ClassC 直接引用了 ClassA(由于 ClassB 继承自 ClassA),因此引用了声明构建完整的类定义需要程序集(即 LibA).

In a different form, this is also the case in the inheritance example. ClassC has a direct reference to ClassA (due to ClassB inherting from ClassA), thus a reference to the declaring assembly (namely LibA) is needed to construct the full class definition.

这篇关于.Net Inheritance - 自动依赖引用行为问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)