繁体   English   中英

遗留和 SDK 样式 C# 项目之间神秘的名称解析差异

[英]Mysterious name resolution differences between legacy and SDK-style C# projects

我在尝试将 .NET 4.6.1 项目的遗留解决方案转换为新的 SDK 样式项目格式时遇到了这个令人困惑的名称解析问题。 我能够创建一个最小的重现解决方案LegacyVsSdkStyleProjectNameResolution ,它位于 GitHub 此处:

https://github.com/PaloMraz/LegacyVsSdkStyleProjectNameResolution.git

该解决方案包含:

  • 3 个针对 .NET Framework 4.6.1 的遗留项目位于“遗留”解决方案文件夹中; 项目名称以“Legacy.”开头)。
  • 3 个 SDK 样式的项目,目标为 .NET,位于“Sdk”解决方案文件夹中; 项目名称以“Sdk.”开头。

(请原谅我不直观的程序集/命名空间/class 名称——我无法使用原始名称,也无法使用 devise 更可行的名称)。

依赖项显示在此图像中:

代码图

问题是, Legacy.Common.Configuration项目使用此Bundle class 声明成功编译:

using Legacy.Common.Data;

namespace Legacy.Common.Configuration
{
  public class Bundle
  {
    public Person Person { get; set; }
  }
}

但是Sdk.Common.Configuration会产生编译错误CS0118 ('Person' 是一个命名空间,但像类型一样使用):

using Sdk.Common.Data;

namespace Sdk.Common.Configuration
{
  public class Bundle
  {
    public Person Person { get; set; }
  }
}

谁能解释一下,为什么Sdk.Common.Configuration项目中的 C# 编译器将Person类型符号错误地解析为命名空间Sdk.Common.Person ,但在Legacy.Common.Configuration中却将其正确解析为Legacy.Common.Data.Person class?

在 SDK 风格的项目中,一个项目会自动继承它的依赖项所依赖的所有东西。 在遗留项目中,这必须手动完成,工具会插入对新依赖项所依赖的所有事物的显式引用。

因此,在您的 SDK 样式项目中,Sdk.Common.Configuration 继承了对 Sdk.Common.Person.Management 的引用,因为它引用了 Sdk.Common.Data。


Sdk.Common.Person.Management定义命名空间Sdk.Common.Person:

namespace Sdk.Common.Person.Management
{
  ...
}

而 Sdk.Common.Data 定义了 class Sdk.Common.Data.Person.:

namespace Sdk.Common.Data
{
  public class Person
  {
  }
}

Sdk.Common.Configuration 然后这样做:

using Sdk.Common.Data;

namespace Sdk.Common.Configuration
{
  public class Bundle
  {
    public Person Person { get; set; }
  }
}

在那里, Sdk.Common.Configuration Person考虑using . 它找到Sdk.Common.Person这是一个名称空间,并抱怨因为您正在使用名称空间作为类型。

如果在命名空间中包含using ,则此顺序翻转,编译器将首先搜索Sdk.Common.Data ,然后找到Sdk.Common.Data.Person class:

namespace Sdk.Common.Configuration
{
  using Sdk.Common.Data;

  public class Bundle
  {
    public Person Person { get; set; }
  }
}

有关详细信息,请参阅此答案


至于如何解决这个问题,首先不要定义一个 class 和一个同名的命名空间。 如果您无法避免这种情况,您可以如上所示更改using的位置,或者使用Person class 的完全限定名称。

如果要反映 Sdk.Common.Data 的引用未被 Sdk.Common.Configuration 继承的遗留行为,请在包含 Sdk.Common.Person.Management 的ProjectReference上使用PrivateAsserts="All"

<ProjectReference Include="..\Sdk.Common.Person.Management\Sdk.Common.Person.Management.csproj" PrivateAssets="All" />

这说明 Sdk.Common.Person.Management 是一个私有依赖项,它不会被任何引用 Sdk.Common.Data 的东西继承。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM