C# 没有命名空间的类的公共成员可见性

Use*_*rol 8 .net c# dependencies visibility namespaces

我有一个项目,在本地源中作为MyNuget包发布。该项目引用了一个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}
Run Code Online (Sandbox Code Playgroud)

这种行为的机制是什么?

如何隐藏ThirdPartyExtensions 主解决方案中的可见性?

Kot*_*ote 7

如果您PackageReference对包依赖项使用格式,那么 PrivateAsset您的标签MyNuget .csproj可能会起作用。
https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets

您可能纯粹将依赖项用作开发工具,并且可能不希望将其公开给将使用您的包的项目。在这种情况下,您可以使用 PrivateAssets 元数据来控制此行为。

<PackageReference Include="ThirdPartyNuget" Version="1.0.0">
    <PrivateAssets>compile</PrivateAssets>
</PackageReference>
Run Code Online (Sandbox Code Playgroud)

或者您可以按照此问题中的描述使用:developmentDependencyDo n't include dependency from packages.config file when create NuGet packagepackages.config


对于“为什么公共依赖是默认方式?”这个问题,我会说:它让生活变得更轻松。

使用具有公共依赖项的包会更容易。如果这是默认行为,则更容易将其公开。
例如,许多用于 Web 开发的包依赖于Newtonsoft.json. 要配置序列化,需要公开它。对此还有另一种看法。
也许 MS 的人有一些关于它的统计数据。但我没有看到任何有关这方面的文章。他们只推荐它作为默认方式。


就您的情况而言,我不确定我是否正确复制了它。

在我的测试中,我创建了三个项目:
一个具有空默认命名空间的子包。 在此输入图像描述 参考具有 PrivateAssets 属性的 SubPackage 的一个包。 在此输入图像描述 在此输入图像描述 还有project,它引用Package,但不引用SubPackage。 在此输入图像描述 如果我尝试使用扩展,它不会编译。但如果我使用方法,则会在运行时打印“2” GetNumber

如果我正确理解了问题,这就是期望的结果。
但我不确定它是否适用于您的修补ThirdPartyNuget程序包。


Dil*_*d K 2

如果您没有为类声明命名空间,则使用默认的全局命名空间。全局命名空间是包含未在命名命名空间内声明的命名空间和类型的命名空间。看这里

您可以使用关键字查看没有命名空间的类global。仅当关键字global是限定符的左侧标识符时,它才是全局名称空间别名。有关::详细信息,请阅读此处

In my main solution I reference MyNuget and DO NOT reference ThirdPartyNuget。但你MyNuget提到的ThirdPartyNuget. 这意味着,您的项目也将被引用ThirdPartyNuget

不可能隐藏扩展的可见性,但是......

你的期望和目标看起来很奇怪。但是,您可以执行以下操作:

如果您的目标是:不允许在您的项目中使用该扩展方法,MyNuget您可以使用空命名空间创建相同的扩展类。例如,ThirdPartyNuget项目具有此扩展名(没有命名空间):

public static class ThirdPartyExtensions
{
    public static void DoSome(this string value)
    {
        //Do some
    }
}
Run Code Online (Sandbox Code Playgroud)

只需创建相同的类MyNuget并尝试在您的项目中使用它。您将从编译器中得到不明确的错误:)。

所以,它不会隐藏它,但它不会允许使用这个扩展