我在尝试将.NET 4.6.1项目转换为新的SDK风格的项目格式时遇到了这个令人困惑的名称分辨率问题。我能够创建一个最小的repro解决方案 legacyvssdkstyleprojectnameresolution
,它在github上在此处:
解决方案包含:
- 3个遗产项目针对.NET框架4.6.1居住在“传统” solution's solution's solution's solution's solution folder中;项目名称以“遗产”开头)。
- 3个位于“ SDK”解决方案文件夹中的SDK式项目。项目名称以“ SDK。”开头。
(请原谅我非直觉的汇编 /名称 /类名称 - 我无法使用原始名称,也无法设计更可行的东西)。
依赖项如下所示:
”
lagacy.common.configuration project成功编译了 bundle
类声明:
using Legacy.Common.Data;
namespace Legacy.Common.Configuration
{
public class Bundle
{
public Person Person { get; set; }
}
}
但是 sdk.common.configuration.configuration
产生编译错误 cs0118
('Person'是一个名称空间,但像一种类型一样使用):
using Sdk.Common.Data;
namespace Sdk.Common.Configuration
{
public class Bundle
{
public Person Person { get; set; }
}
}
任何人都可以解释一下,为什么 sdk.common.common.configuration中的C#编译器
Project project project solesolve person
>将符号错误键入命名空间 sdk.common.common.person
,但在 Legacy.common.common.configuration
中,它将其正确解析到 legacy.common.data.person 类?
I encountered this confusing names-resolution problem while trying to convert legacy solution with .NET 4.6.1 projects to the new SDK-style project formats. I was able to create a minimal repro solution LegacyVsSdkStyleProjectNameResolution
, which is on GitHub here:
https://github.com/PaloMraz/LegacyVsSdkStyleProjectNameResolution.git
The solution contains:
- 3 legacy projects targeting .NET Framework 4.6.1 residing in the „Legacy“ solution folder; the project names start with „Legacy.“).
- 3 SDK-style projects targeting .NET residing in the „Sdk“ solution folder; the project names start with „Sdk.“.
(Please forgive me the non-intuitive assembly / namespace / class names – I could not use the original names and was not able to devise something more feasible).
The dependencies are shown in this image:

The problem is, the Legacy.Common.Configuration
project successfuly compiles with this Bundle
class declaration:
using Legacy.Common.Data;
namespace Legacy.Common.Configuration
{
public class Bundle
{
public Person Person { get; set; }
}
}
But the Sdk.Common.Configuration
produces compilation error CS0118
('Person' is a namespace but is used like a type):
using Sdk.Common.Data;
namespace Sdk.Common.Configuration
{
public class Bundle
{
public Person Person { get; set; }
}
}
Can anybody please explain, why the C# compiler in the Sdk.Common.Configuration
project resolves the Person
type symbol incorrectly to namespace Sdk.Common.Person
, but in the Legacy.Common.Configuration
it resolves it correctly to Legacy.Common.Data.Person
class?
发布评论
评论(1)
在SDK风格的项目中,一个项目将自动继承其依赖性所依赖的所有内容。在旧版项目中,必须手动完成,工具将明确的引用插入了对新依赖依赖的所有事物的明确引用。
因此,在您的SDK风格项目中,sdk.common.configuration继承了对sdk.common.person.management的引用,它是因为它引用了sdk.common.data。
sdk.common.person.management定义命名空间SDK.COMMON.PERSON:
while sdk.common.data定义了类SDK.Common.data.person。:SDK.Common.Configuration,
进行此操作。
然后
sdk.common.configuration
(and sdk.common和sdk)person
之前,它考虑使用。它找到sdk.common.person
是一个名称空间,并且因为使用名称空间作为类型而抱怨。如果您在名称空间内使用
使用
,则此订单翻转,并且编译器将搜索sdk.common.data
first ,并找到<代码> sdk.common.data.person 类:有关详细信息。
至于如何解决此问题,首先不要定义具有相同名称的类和名称空间。如果无法避免这种情况,则可以使用来更改
的位置,如上所述,或使用
Person
类的完全合格名称。如果您想镜像sdk.common.data的遗留行为,而不是由sdk.common.configuration继承,请使用
privateasserts =“ all”
onproject> projectReferference
,其中包括包括sdk.common.person.management。这指出sdk.common.person.management是一种私人依赖性,它并非由引用sdk.common.data的任何内容继承。
In SDK-style projects, a project will automatically inherit all of the things that its dependencies depend on. In legacy projects this had to be done manually, with the tooling inserting explicit references to all of the things that a new dependency depended on.
So in your SDK-style project, Sdk.Common.Configuration is inheriting a reference to Sdk.Common.Person.Management, by virtue of the fact that it references Sdk.Common.Data.
Sdk.Common.Person.Management defines the namespace Sdk.Common.Person:
While Sdk.Common.Data defines the class Sdk.Common.Data.Person.:
Sdk.Common.Configuration then does this:
There, the compiler searches the namespace
Sdk.Common.Configuration
(and Sdk.Common, and Sdk) forPerson
before it considers thatusing
. It findsSdk.Common.Person
which is a namespace, and complains because you're using a namespace as a type.If you include the
using
inside the namespace, this order flips, and the compiler will searchSdk.Common.Data
first, and find theSdk.Common.Data.Person
class:See this answer for details.
As for how to solve this, first off don't define a class and a namespace with the same name. If you can't avoid this, you can either change the location of the
using
as shown above, or use the fully-qualified name of thePerson
class.If you want to mirror the legacy behaviour of Sdk.Common.Data's references not being inherited by Sdk.Common.Configuration, use
PrivateAsserts="All"
on theProjectReference
which includes Sdk.Common.Person.Management.This states that Sdk.Common.Person.Management is a private dependency, which isn't inherited by anything which references Sdk.Common.Data.