提问人:UserControl 提问时间:3/26/2022 最后编辑:UserControl 更新时间:4/5/2022 访问量:568
没有命名空间的类的 C# 公共成员可见性
C# public members visibility of a class with no namespace
问:
我有一个项目,我将其作为 MyNuget 包发布到本地源中。该项目引用了一个 ThirdPartyNuget,该 ThirdPartyNuget 具有公共静态类,其中有公共扩展方法。ThirdPartyExtensions
IQueryable
现在,在我的主要解决方案中,我引用了 MyNuget,并且不引用 ThirdPartyNuget。不过,Visual Studio 2022 显示了 中的扩展方法。为什么?ThirdPartyExtensions
我不希望出现这种情况,因为我认为 ThirdPartyNuget 是 MyNuget 的实现细节。
ThirdPartyNuget 中的程序集经过混淆处理,类看起来很奇怪,因为它没有命名空间。以下是我在调试器中看到的内容:ThirdPartyExtensions
typeof(ThirdPartyExtensions).Name == typeof(ThirdPartyExtensions).FullName == "ThirdPartyExtensions"
typeof(ThirdPartyExtensions).Namespace == null
typeof(ThirdPartyExtensions).GUID == {00000000-0000-0000-0000-000000000000}
这种行为的机制是什么?
如何在主解决方案中隐藏可见性?ThirdPartyExtensions
答:
如果未为类声明命名空间,则使用默认的全局命名空间。全局命名空间是包含未在命名命名空间中声明的命名空间和类型的命名空间。请看这里。
您可以使用关键字查看没有命名空间的类。仅当关键字是限定符的左侧标识符时,该关键字才是全局命名空间别名。欲了解更多信息,请阅读此处global
global
::
In my main solution I reference MyNuget and DO NOT reference ThirdPartyNuget
.但是你引用了.这意味着,您的项目也将被引用。MyNuget
ThirdPartyNuget
ThirdPartyNuget
无法隐藏扩展的可见性,但是......
你的期望和目标看起来很奇怪。Hovewer,你可以做这样的事情:
如果你的目标是:不允许在你的项目中使用该扩展方法,你可以创建具有空命名空间的相同扩展类。例如,项目具有以下扩展名(无命名空间):MyNuget
ThirdPartyNuget
public static class ThirdPartyExtensions
{
public static void DoSome(this string value)
{
//Do some
}
}
只需在 中创建相同的类并尝试在您的项目中使用它。您将从编译器:)中得到模棱两可的错误。MyNuget
因此,它不会隐藏它,但不允许使用此扩展
评论
ThirdPartyNuget
如果你对你的包依赖项使用格式,那么 你的标签就可以了。
https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assetsPackageReference
PrivateAsset
MyNuget
.csproj
您可能纯粹将依赖项用作开发工具,并且可能不希望将其公开给将使用包的项目。在此方案中,可以使用 PrivateAssets 元数据来控制此行为。
<PackageReference Include="ThirdPartyNuget" Version="1.0.0">
<PrivateAssets>compile</PrivateAssets>
</PackageReference>
或者,可以按照以下问题
中所述使用 :创建 NuGet 包时,不要包含 packages.config 文件中的依赖项developmentDependency
packages.config
至于“为什么公共依赖是默认方式?”的问题,我会说:它让生活更轻松。
使用具有公共依赖项的包更容易。如果这是默认行为,则更容易将它们公开。
例如,许多用于 Web 开发的软件包都依赖于 .要配置序列化,需要公开它。关于这一点的另一种看法。
可能 MS 的人对此有一些统计数据。但我没有看到任何关于这方面的文章。他们只推荐它作为默认方式。Newtonsoft.json
就您的情况而言,我不确定我是否正确复制了它。
在我的测试中,我创建了三个项目:
一个默认命名空间为空的子包。一个包,引用具有 PrivateAssets 属性的 SubPackage。
和 project,它引用 Package,但不引用 SubPackage。
如果我尝试使用扩展,它不会编译。
但是如果我使用方法,则在运行时打印“2”。
GetNumber
如果我正确理解了问题,那就是想要的结果。
但我不确定,它是否适用于您的修补包。ThirdPartyNuget
评论
PrivateAssets
NugetSubPack.dll
NugetSubPack.dll
compile
<PrivateAssets>compile</PrivateAssets>
上一个:隐藏第三个依赖项目中的命名空间
评论