如何指定几个不明确的点符号命名空间之一

How do specify one of several dot-notated namespaces which are ambiguous

提问人:Dallas Caley 提问时间:1/11/2023 最后编辑:Dallas Caley 更新时间:1/21/2023 访问量:70

问:


编辑。。。

请注意,我正在更改对文件夹的虚假引用,以更正确地反映它们不是文件夹而是命名空间。这里的一些评论来自该更改之前


我对 C# 很陌生,所以如果我说错了什么,请原谅我。

我正在一个大型解决方案中工作,其中包含许多项目。

我被要求将命名空间中定义的特定类从一个项目移动到另一个项目。但是,当我这样做时,问题在于有一个对象定义不再被正确引用。下面是一个示例:

原始结构:

此文件:

Main\Second.Level.Data\Second.Level.Data.csproj:

最初里面有这样一行代码:

<Compile Include="Some\Nested\File\Way\Down.cs" />

此外,这里还引用了实际文件:

Main\Second.Level.Data\Some\Nested\File\Way\Down.cs

新结构:

首先,我们从 'Main\Second.Level.Data\Second.Level.Data.csproj 中删除了 Compile 行,并在新命名空间中添加了一行类似的代码,如下所示:

File: Main\Main.DataAccess\Main.DataAccess.csproj

添加了新的代码行:

<Compile Include="New\Location\of\Down.cs" />

我们将实际文件移动到现在的新位置:

Main\Main.DataAccess\New\Location\of\Down.cs

完成此操作后,除了一个引用之外,所有引用(也就是所有 using 语句)似乎都有效。有一个 using 语句是这样的:

using Main.Second.Level.Data.Yet.Another.Nested.File.Objects

在旧命名空间中,此 using 语句工作正常,但在新命名空间中则不然。具体来说,它在第三个元素(级别)上失败。我的IDE出现错误,说“无法解析符号'Level'”。

我高度怀疑发生这种情况的原因是实际上存在另一个命名空间,该命名空间仅命名为“Main.Second”,其中包含它自己的 Main.Second.csproj 文件。我不将此文件夹或其中的文件用于任何用途,但是我不明白系统如何知道以下两者之间的区别:

using Main.Second.Level.Data.Yet.Another.Nested.File.Objects

using Main.Second.Some.Other.Unrelated.Stuff

也就是说,我不明白点表示法如何判断命名空间名称的开始或结束位置。

附录#1:

我已经确定问题是目标项目的 csproj 文件中没有对新项目的项目引用(或者至少我相当确定是这种情况)。为了解决这个问题,我尝试手动添加此引用。请注意,我正在使用 JetBrains Rider IDE,并尝试了几种添加引用的自动化方法,但没有一种有效。

为了添加引用,我找到了包含所有其他项目引用的 ItemGroup 块,并添加了一个新块。它看起来像这样:

<ItemGroup>
  <ProjectReference Include "..\Other.Project\Other.Project.csproj">
    <Project>{fh9w8es3-nota-real-guid-example1}</Project>
    <Name>Other.Project</Name>
  </ProjectReference>
  <ProjectReference Include "..\Main.Second.Level\Other.Project.csproj">
    <Project>{AD8234HS-NOTA-REAL-GUID-EXAMPLE2}</Project>
    <Name>Main.Second.Level</Name>
  </ProjectReference>
</ItemGroup>

请注意,在执行此操作时,我必须为 Project 元素提供一个 guid。我推断(经过研究)这个 guid 将是解决方案根目录下的解决方案文件中当前存在的 guid,具体来说,它是为该项目显示的第二个 GUID。我上面的示例正是我编写代码的方式(特别是从解决方案文件复制的 GUID 都是大写的,而 csproj 文件中的 GUID 不是。

然而,这并不能解决我的问题。然而,我觉得我非常接近一个解决方案。

C# .NET 命名空间

评论

0赞 Jon Skeet 1/11/2023
using指令和文件结构仅在约定情况下彼此相关。您需要查看要访问的类中的命名空间声明。定义了您需要的指令。using
0赞 Dallas Caley 1/11/2023
是的,我被告知这一点,但它不起作用。引用对象的命名空间尚未更改,但无法从新位置访问它。是否可能无法在另一个项目中引用一个项目的对象?
1赞 Guru Stron 1/11/2023
很难说问题出在哪里。你能以某种方式提供一个最小的可重复的例子吗?
0赞 Jon Skeet 1/11/2023
事实上,如果没有任何方法可以重现这个问题,我们根本无法提供帮助。你绝对可以在另一个项目中引用一个项目的类型,只要它是公共的,并且有一个从使用项目到提供项目的引用(直接或间接)。但同样,如果没有复制品,很难说出任何具体的东西。
0赞 Dallas Caley 1/11/2023
谢谢大家,我可能需要几天时间才能创建类似的东西(不幸的是,我无法公开实际代码)。我在新项目的 .csproj 文件中发现了一个名为“ProjectReference”的东西,它似乎指示了引用外部项目的确切方式,我认为我需要进一步研究。

答:

0赞 Dallas Caley 1/21/2023 #1

我提出的原始问题的正确答案是,您需要将 ProjectReference 添加到 ItemGroup,如我在原始问题上发布的附录中所述。

然而,在我的特殊情况下,这是不可能的,因为这样做会引起循环引用。例:

项目A:参考了项目B 项目 A:广泛定义和使用内部类,并在项目 B 中使用类

项目 B:具有仅在项目 B 中使用的类

我的更改试图将项目 A 中的一个类添加到项目 B 中,但这样做需要添加对项目 A 的反向引用,这就是导致循环引用的原因。

为了解决这个问题,我做了以下工作:

  1. 在项目 B 中定义了一个接口,该接口适用于我在项目 A 中定义的新类

  2. 使 Project A 类扩展此接口

  3. 更改对项目 B 中的项目 A 类的引用,以引用接口而不是定义的类。这样做消除了对反向引用的需要。

抱歉,这太模糊了,但它是专有代码(而且非常复杂),因此在这里发布不切实际,但我想我已经封装了解决方案的要点。