C#/。NET中仅命名空间的类可见性?


87

在C#中,您是否可以使类仅在其自己的名称空间中可见而无需使用其他程序集?这对于不应该在其他地方使用的典型帮助器类似乎很有用。(即Java所谓的package-private类)


我不明白你的问题。我删除了我的答案,因为您的意思不是“内部”?
Zyphrax

3
@nos:您是否在寻找与Java包级可见性相同的东西?
约翰·桑德斯

Answers:



79

您可以创建类,internal但这只会阻止程序集之外的任何人使用该类。但是,您仍然必须为每个要使用的命名空间创建一个单独的程序集。我猜想这就是为什么你会不会想这样做。

获取C#编译器以增强命名空间可见性

这里有一篇文章(C#中的名称空间可见性),展示了一种使用部分类作为“假名称空间”形式的方法,您可能会发现它有用。

作者指出,这并不完美,他讨论了缺点。主要问题是C#设计人员设计的C#不能以这种方式工作。这严重偏离了C#/。NET中的预期编码实践,而C#/。NET是.NET Framework最大的优势之一。

这是一个巧妙的把戏……现在就不要做。


1
刚刚找到一个例子:System.Net.Mime.MediaTypeNames.Application
Bitterblue

文章说,您必须在每个调用之前添加“命名空间”名称,但在C#6“使用静态”中则不需要。您可以将“命名空间”设置为静态的部分类,然后在客户端代码中编写“使用静态的”
Pumkko

@Pumkko该类不需要是静态的就能使用'using static'语句,尽管如果将其用作命名空间,则它还是应该是静态的。
模糊逻辑

21

内部是程序集(严格来说是模块)的隐私。它对名称空间可见性没有影响。

实现一个类与同一程序集中其他类的隐私的唯一方法是使一个类成为内部类。

在这一点上,如果该类是私有的,则该类或外部类本身以外的任何内容都不可见。

如果受保护,则对所有人都可见(在私有时可以看到它),但对外部类的子类也可见。

public class Outer
{
    private class Hidden     { public Hidden() {} }
    protected class Shady    { public Shady() {} }
    public class Promiscuous { public Promiscuous() {} }
}

public class Sub : Outer
{
    public Sub():base() 
    {
        var h = new Hidden();      // illegal, will not compile
        var s = new Shady();       // legal
        var p = new Promiscuous(); // legal
    }
}

public class Outsider 
{
    public Outsider() 
    {
        var h = new Outer.Hidden();      // illegal, will not compile
        var s = new Outer.Shady()        // illegal, will not compile
        var p = new Outer.Promiscuous(); // legal
    }
}

本质上,实现所需目标的唯一方法是将外部类用作命名空间的形式并限制在该类内。


@ShuggyCoUK:公共类Sub:外部应密封公共类Sub:外部??? +1虽然...我的作品
IAbstract

0

如果只有一个程序集,则可以根据需要在该程序集中定义多个名称空间,但是无论您在IDE中应用什么修饰符,您始终可以看到其他名称空间中的类。


0

不确定是否直接可行,但有几种伪造它的好方法是:

1)让需要这种东西的类从单个类继承,该单个类将helper类作为内部类。

2)使用扩展方法,然后仅在命名空间中引用扩展方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.