调试一个有趣的错误,我为了隔离它而剥离了一个解决它的裸骨的解决方案。该问题表现为经典构建错误(未引用程序集)。
有趣的是,在无法构建的程序集中没有使用有问题的程序集中的类型。移动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)]
所有项目均引用System
和System.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
问题在以下情况下消失:
using
语句放在Gamma
命名空间块之外的Foo
中。CLSCompliant
程序集的Baz
属性。Alpha
不会继承Beta
(即使Foo
仍然引用Bar
而Alpha
仍以其他方式使用Beta
,通过撰写它的例子。)。Foo
无法访问Gamma
(例如,将Gamma
的名称空间更改为Baz
)。Bar
中添加了对Baz
的引用。其他项目是否符合CLS并不重要。在他们真正的解决方案中
目标框架似乎不会影响这种行为
我们在Gamma.cs
命名空间块中导入的命名空间无关紧要,我们在这里写using System;
,但它可以是任何东西。删除所有using
语句(或将它们放在命名空间块之外)会使问题消失,如上所述。
using
语句会影响该行为?Bar
的引用,即使它没有意义? (我们没有使用Alpha
继承类型。)我知道编译器永远不会出错,但是当你不知道发生了什么时(特别是using
语句放置事物)它仍然看起来像一些严重的伏都教。我已经浏览了ECMA-335(CLI)的I.11部分,其中包含了CLS规则的参考,但我无法确定哪一个是我应该理解的,但显然不是。
如果问题不明显,您应该能够通过简单地在空C#项目中逐字复制代码并添加相同的引用来一致地重现它。