你能用C#创建私有类吗?

时间:2010-08-26 10:56:02

标签: c# language-features

这是.NET哲学家的一个问题:

据我了解,微软有意识地否认在C#中使用私人课程。为什么他们这样做,他们这样做的理由是什么?

例如,我正在构建一个包含报告工具的大型应用程序。此工具使用许多业务对象,这些业务对象仅在报表工具中使用,而不在项目的其他部分中使用。我想将它们封装起来,仅用于报告工具本身。

很好的决定是在VS中为这个工具创建单独的项目,我会这样做,但我很有意思,如果我不能这样做怎么办 - 因为我们的架构不够好,而且我们有一个大单项目。

在“私有类”后面我指的是一个不能在任何其他命名空间中使用的类,除了它自己的。

我的问题不是 - 我怎么能模拟这个,或者用另一种方式做。我只是想知道,为什么不在没有任何父类的情况下使用带有class关键字的private关键字。我认为应该有一些原因,我想知道

6 个答案:

答案 0 :(得分:21)

允许类对命名空间是私有的,将无法实现有意义的保护级别。

世界上任何程序集都可以简单地引用你的dll,并开始在你的命名空间中编写代码来访问你所谓的私有类。

我认为这可能是你从微软获得的答案。

答案 1 :(得分:15)

有一个解决方法,但你可能不喜欢它。

使用namespace

,而不是使用public static partial class来定位您的课程

在:

namespace MyCompany.Foo {
  class Bar { }
  public class Baz { }
}

后:

namespace MyCompany {
  public static partial class Foo {
    private class Bar { }
    public class Baz { }
  }
}

此构造与命名空间一样,可以跨越同一项目中的多个文件。但与名称空间不同,它不能“逃避”您的项目(其他项目无法定义Foo内的其他成员。)

还有一个额外的好处,即Foo内的代码可以seem to have no class使用实用方法。

缺点是,要在假名称空间之外使用非私有类,必须在Foo内引用它们:

using MyCompany;

// ...

var baz = new Foo.Baz();

这可以通过使用类的别名来缓解:

using Baz = MyCompany.Foo.Baz;

// ...

var baz = new Baz();

但是你必须为你想要使用的每个非私人类做这件事。

<强>更新

有趣的是,C#6将有static using statements,这可以有效地改进此提案,以使用public static partial class作为“模块”。您只需“使用”“模块”即可直接访问其类型。

希望它会像这样工作:

using MyCompany.Foo;

// ...

var baz = new Baz();

就像Foo是命名空间一样。

答案 2 :(得分:11)

您可以创建一个私有类,作为另一种类型的成员:

public class Outer {
  // ...
  private class Inner {
    // ...
  }
}

Inner仅对Outer的成员可见。

在最外层(即在命名空间中)private根据其定义是没有意义的(因为没有什么是私有的)。而是使用internal(仅对包含程序集的成员可见)。

答案 3 :(得分:2)

您可以定义私有类,但只能由其包含的类使用。

如果你想要一个只在特定程序集中可见的类(DLL / EXE / etc。),那么你应该将它声明为internal(VB中的Friend

答案 4 :(得分:1)

是的,但如果命名空间被分割为多个程序集,你可以使用内部类和internalsvisibletoAttribute进行非常接近的模拟。

还要记住,另一个类中的类可以是外部类的私有。为此,可以将外部类视为命名空间。

答案 5 :(得分:1)

所以我猜你想要这样做

namespace Baz
{
    private class foo
    {
        private int _bar;
    }
}

如果是的话。然后foo将服务器的目的是什么。在命名空间你可以比内部更严格,并使用该类。如果我可以这样做,我将在哪里使用它。

这就是你有这个编译时验证的原因。

现在在公共类中,拥有一个私有类是有意义的。我无法更好地解释这个Private inner classes in C# - why aren't they used more often?