gpt4 book ai didi

.net - CLSCompliant(true) 拖入未使用的引用

转载 作者:行者123 更新时间:2023-12-03 09:29:28 25 4
gpt4 key购买 nike

谁能解释以下行为?

总之,如果您在 Visual Studio 2008 中创建多个符合 CLS 的库并让它们共享一个公共(public)命名空间根,则引用另一个库的库将需要对该库的引用的引用,即使它不使用它们。

这很难用一句话来解释,但这里有一些重现行为的步骤(密切注意命名空间):

创建一个名为 LibraryA 的库并向该库添加一个类:

namespace Ploeh
{
public abstract class Class1InLibraryA
{
}
}

通过添加 [assembly: CLSCompliant(true)] 确保库符合 CLS到 AssemblyInfo.cs。

创建另一个名为 LibraryB 的库并引用 LibraryA。将以下类添加到 LibraryB:
namespace Ploeh.Samples
{
public class Class1InLibraryB : Class1InLibraryA
{
}
}


namespace Ploeh.Samples
{
public abstract class Class2InLibraryB
{
}
}

确保 LibraryB 也符合 CLS。

请注意,Class1InLibraryB 派生自 LibraryA 中的类型,而 Class2InLibraryB 不是。

现在创建名为 LibraryC 的第三个库并引用 LibraryB(但不是 LibraryA)。添加以下类:
namespace Ploeh.Samples.LibraryC
{
public class Class1InLibraryC : Class2InLibraryB
{
}
}

这仍然应该编译。请注意,Class1InLibraryC 派生自 LibraryB 中的类,该类不使用 LibraryA 中的任何类型。

另请注意,Class1InLibraryC 是在一个命名空间中定义的,该命名空间是 LibraryB 中定义的命名空间层次结构的一部分。

到目前为止,LibraryC 没有对 LibraryA 的引用,并且由于它不使用 LibraryA 中的任何类型,因此解决方案可以编译。

现在也使 LibraryC CLS 兼容。突然,解决方案不再编译,给你这个错误信息:

The type 'Ploeh.Class1InLibraryA' is defined in an assembly that is not referenced. You must add a reference to assembly 'Ploeh, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.



您可以通过以下方式之一再次编译解决方案:
  • 从库中删除 CLS 合规性 C
  • 添加对 LibraryA 的引用(尽管您不需要它)
  • 更改 LibraryC 中的命名空间,使其不属于 LibraryB 的命名空间层次结构(例如,更改为 Fnaah.Samples.LibraryC)
  • 更改 Class1InLibraryB 的命名空间(即 LibracyC 未使用的命名空间),使其不在 LibraryC 的命名空间层次结构中(例如,更改为 Ploeh.Samples.LibraryB)

  • namespace 层次结构和 CLS 合规性之间似乎存在一些奇怪的相互作用。

    可以通过选择上面列表中的一个选项来解决这个问题,但是任何人都可以解释这种行为背后的原因吗?

    最佳答案

    我查看了 CLS 的官方文档 (http://msdn.microsoft.com/en-us/netframework/aa569283.aspx),但在我找到一个简单的答案之前,我的脑袋就爆炸了。

    但我认为基础是编译器为了验证 LibraryC 的 CLS 合规性,需要查看与 LibraryA 可能的命名冲突。

    编译器必须验证所有“在定义程序集之外可访问或可见的类型部分”(CLS 规则 1)。

    由于公共(public)类 Class1InLibraryC 继承 Class2InLibraryB,因此它还必须验证对 LibraryA 的 CLS 合规性,特别是因为“Ploeh.*”现在是“在范围内”,适用于 CLS 规则 5“在符合 CLS 的范围中引入的所有名称都应是不同的独立的种”。

    更改 Class1InLibraryB 或 Class1InLibraryC 的命名空间以使它们变得不同似乎使编译器不再有可能发生名称冲突。

    如果您选择选项 (2),添加引用并编译,您将看到该引用实际上并未在生成的程序集元数据中标记,因此这只是编译/验证时的依赖。

    关于.net - CLSCompliant(true) 拖入未使用的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1254078/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com