.NET继承 - 自动依赖引用行为问题 [英] .Net Inheritance - Automatic dependency referencing behavior issue

查看:133
本文介绍了.NET继承 - 自动依赖引用行为问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



**注意商量后编**



项目力霸 - 具有ClassA的

 命名空间力霸
{
公共类ClassA的
{
公共重写字符串的ToString()
{
返回 A类的逻辑!;
}
}
}

项目LibB - 具有ClassB的

 使用力霸; 

命名空间LibB
{
公共类ClassB的
{
公共ClassA的一个;

公共ClassB的()
{
A =新ClassA的();
}

公共对象美孚()
{
返回;
}
}
}

项目的LibC - 具有ClassC

 使用LibB; 

命名空间的LibC
{
公共类ClassC
{
公共ClassB的B:

公共ClassC()
{
B =新ClassB的();
}

公共对象美孚()
{
返回b.Foo();
}
}
}



最后一个测试车手

 使用系统; 
使用libc的;

命名空间壳牌
{
类节目
{
静态无效的主要(字串[] args)
{
ClassCÇ =新ClassC();
Console.WriteLine(c.Foo());
}
}
}

如果你编译这个现在,一切都将正常工作。如果检查的LibC的二进制文件夹的内容,你会看到,它通过依赖链自动回滚,以确定它需要在力霸和LibB



不过如果你改变ClassB的从A级
继承,如

 使用力霸; 

命名空间LibB
{
公共类ClassB的:ClassA的
{
ClassA的一个;
}
}



试图编译,你会得到错误



错误2类型'LibA.ClassA'在未引用的程序集的定义。您必须添加一个引用程序集力霸,版本= 1.0.0.0,文化=中立,公钥=空'。


**原始的问题**



有谁知道为什么(无论是或的MSBuild视觉工作室),它是足够聪明,引用时力霸的ClassA ClassB的成员,但它不是足够聪明,引用力霸当ClassA的是基类ClassB的吗?



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



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



我听到一些什么定义为直接或间接的引用。然而,直接显然不只是知名度作用域,这似乎是继承和类型的实际使用情况。



没有继承,测试驱动程序是足够聪明的化解和自动引用力霸,LibB或是libc。



有一个公开成员ClassB的ClassA的可见的,但单独不会产生编译/链接错误。



调试器肯定是从测试驱动器解决ClassA的,所以它清楚地加载正确的程序集。



因此,所有考虑到这一点。我得到整个直接和间接的东西了。



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


解决方案

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



如果一个组件被编译和一类从一个类继承另一个组件,即参考需要建造它。



LibB 仅包含为添加的信息在类定义的 ClassB的,它不会从力霸复制的一切(这会产生不一致的代码,如果力霸更新和 ClassA的,而这样做, LibB 仍然会包含旧被改变信息)。



因此,要使用的LibC 继承的类定义,它同时需要从<$ c中的信息$ C>力霸(为 ClassA的)和 LibB ClassB的)来构建它,从而直接引用力霸是必要的。



在这个例子中,以不同的组件类的所有引用是私有的,因此只剩下一级别neeed( ClassC 并不需要了解 ClassA的因为有那类没有直接使用)。如果 ClassA的 ClassB的的使用是一个公共领域或欢迎使用属性, ClassC 将有一个直接引用 ClassA的并需要直接引用的类定义以及(参考力霸的LibC )。



在不同的形式,这也是在继承的情况为例。 ClassC 有一个直接引用 ClassA的(由于 ClassB的从inherting ClassA的),从而在声明组件(即力霸参考)是需要构建完整的类定义


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

If you have a solution with 3 projects

** NOTE Edited after discussion **

Project LibA - Has a ClassA

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

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;
        }
    }
}

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();
        }
    }
}

Finally a test driver

using System;
using LibC;

namespace Shell
{
    class Program
    {
        static void Main(string[] args)
        {
            ClassC c = new ClassC();
            Console.WriteLine(c.Foo());
        }
    }
}

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

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

using LibA;

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

attempt to compile, you'll get the error

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'.

** Original Question **

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.

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

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

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.

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 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).

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.

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).

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继承 - 自动依赖引用行为问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆