Mandelbug:编译器需要的不需要的传递程序集引用; CLS合规;能见度

时间:2014-07-11 14:58:33

标签: c# .net dependencies .net-assembly cls-compliant

概述

调试一个有趣的错误,我为了隔离它而剥离了一个解决它的裸骨的解决方案。该问题表现为经典构建错误(未引用程序集)。

有趣的是,在无法构建的程序集中没有使用有问题的程序集中的类型。移动using语句并删除CLS合规性属性会使错误消失,这意味着隐藏的符号可见性规则(可能)生效。

代码

Mandelbug/
|-- Mandelbug.sln
`-- src
    |-- Bar
    |   |-- Bar.csproj
    |   `-- Beta.cs
    |-- Baz
    |   |-- Baz.csproj
    |   |-- Gamma.cs
    |   `-- Properties
    |       `-- AssemblyInfo.cs
    `-- Foo
        |-- Alpha.cs
        `-- Foo.csproj

除了项目(csproj)文件外,整个代码库都是逐行显示的。

富/ Alpha.cs

namespace Foo {
    public class Alpha : Bar.Beta { }
}

酒吧/ Beta.cs

namespace Bar {
    public class Beta { }
}

巴兹/ Gamma.cs

namespace Foo {
    using System;
    public class Gamma { }
}

巴兹/属性/ AssemblyInfo.cs中

[assembly: System.CLSCompliant(true)]

依赖关系

enter image description here

所有项目均引用SystemSystem.Core Baz引用Foo Foo引用Bar

Foo.Alpha需要从Bar.Beta依赖继承 Baz.Gamma需要真实解决方案中Foo中其他类型的依赖关系(与Alpha无关)。在这个精简的解决方案中没有使用,但问题仍然存在。

编译错误

描述:The type 'Bar.Beta' is defined in an assembly that is not referenced. You must add a reference to assembly 'Bar, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
档案:src\Baz\Gamma.cs
行:1
专栏:11
项目:Baz

行为

问题在以下情况下消失:

  1. using语句放在Gamma命名空间块之外的Foo中。
  2. 删除CLSCompliant程序集的Baz属性。
  3. Alpha不会继承Beta(即使Foo仍然引用BarAlpha仍以其他方式使用Beta,通过撰写它的例子。)。
  4. Foo无法访问Gamma(例如,将Gamma的名称空间更改为Baz)。
  5. Bar中添加了对Baz的引用。
  6. 其他项目是否符合CLS并不重要。在他们真正的解决方案中 目标框架似乎不会影响这种行为 我们在Gamma.cs命名空间块中导入的命名空间无关紧要,我们在这里写using System;,但它可以是任何东西。删除所有using语句(或将它们放在命名空间块之外)会使问题消失,如上所述。

    问题

    1. 什么CLS规则会影响该行为?
    2. 为什么在命名空间块内部或外部放置using语句会影响该行为?
    3. 这不仅仅是一种好奇心,我们实际上有一个具有这种传递依赖性的项目 - 我们是否应该添加对Bar的引用,即使它没有意义? (我们没有使用Alpha继承类型。)
    4. 备注

      我知道编译器永远不会出错,但是当你不知道发生了什么时(特别是using语句放置事物)它仍然看起来像一些严重的伏都教。我已经浏览了ECMA-335(CLI)的I.11部分,其中包含了CLS规则的参考,但我无法确定哪一个是我应该理解的,但显然不是。

      如果问题不明显,您应该能够通过简单地在空C#项目中逐字复制代码并添加相同的引用来一致地重现它。

0 个答案:

没有答案