【问题标题】:Can you create private classes in C#?你可以在 C# 中创建私有类吗?
【发布时间】:2011-04-04 05:11:08
【问题描述】:

这是 .NET 哲学家的问题:

据我了解,Microsoft 有意识地拒绝在 C# 中使用私有类。他们为什么这样做?他们这样做的理由是什么?

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

伟大的决定是在 VS 中为这个工具创建单独的项目,我会这样做,但我很有趣,如果我不能这样做 - 例如我们的架构不够好,我们有大的单一项目。

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

我的问题不是——我该如何模拟这个,或者以其他方式做。我只是想知道,为什么不在没有任何父类的情况下将 private 关键字与 class 关键字一起使用。我在想应该有什么原因,我想知道它

【问题讨论】:

  • 这是内部的,不是私人的。
  • 嘿,我知道什么是内部的,以及公共内部的私有 =) Im just wondering, why I cant 为命名空间创建私有类 - 也许所有这些都是模拟的,但他们为什么否认这一点?
  • @Archeg 如果它是私人的,你希望谁能够看到它?
  • 在同一命名空间中创建的其他类。当您使用简单的原则时-对于 VS 中的单个文件夹-单个命名空间-将使用此方法。您可以从同一个文件夹或其中的文件夹中使用此类
  • @Archeg:我认为你认为命名空间比它们更重要。它们纯粹是代码编写者的命名上下文。即使在运行时,它们也没有任何用途(所有元数据和引用都以全名表示)。请记住,一个程序集可以包含许多命名空间,并且一个命名空间可以跨多个程序集拆分。

标签: c# language-features


【解决方案1】:

没错,但如果命名空间被拆分为多个程序集,您可以使用内部类和internalsvisibletoAttribute 对此进行非常接近的模拟。

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

【讨论】:

  • 我写了关于内部的文章。 its cool but not the same. Maybe I have a situation, where I cant 把我的项目分成很多
【解决方案2】:

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

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

Inner 仅对Outer 的成员可见。

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

【讨论】:

  • 是的,我知道。但这不是答案 - 我需要在多个类中使用我的对象,而具有 20 个内部类的类是一个问题 =)
【解决方案3】:

你可以定义一个私有类,但它只能被它的包含类使用。

如果您想要一个仅在特定程序集(DLL/EXE/等)中可见的类,则应将其声明为internal(VB 中为Friend

【讨论】:

    【解决方案4】:

    允许类对命名空间来说是私有的,不会实现有意义的保护级别。

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

    我认为这可能就是你从微软那里得到的答案。

    【讨论】:

    • 我喜欢,你抓住了我的想法=) 可能是答案
    • 我可以看到这个值 - 如果你将它标记为 privatenamespace internal NewClass() {} 这将防止这种情况。 (或者如果“privatenamespace”是隐式内部的。)
    • @tim:我不确定我能不能。我读到的原始问题是这样说的:“鉴于我已经有了一个没有足够汇编级封装的体系结构,为什么该语言没有给我一个替代解决方案?”你不应该将语言特性作为糟糕架构的解决方法——你应该首先鼓励/实施良好的架构。
    • 我现在的情况是,命名空间私有的类会派上用场。这是旧代码,自构建框架以来,被认为是好的架构已经发生了变化。加号数据已更改。 Plus 功能已更改。加上工具已经改变。在进行巨大飞跃和重构架构之前,使用命名空间模拟程序集将是一个很好的中间步骤。通过这种方式,我可以在要求任何人花费€s 之前证明重构的好处。同时保持系统运行而无需进行大的重写。
    【解决方案5】:

    所以我猜你想这样做

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

    如果是。那么 foo 服务的目的是什么。在命名空间你可以比 internal 更具限制性,并且可以使用该类。如果我能做到这一点,我将在哪里使用它。

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

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

    【讨论】:

      【解决方案6】:

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

      不要使用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 中定义其他成员)。

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

      缺点是,要在假命名空间之外使用非私有类,您必须在 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 是一个命名空间一样。

      【讨论】:

      • 不,我喜欢你的回答,its great! =) I will not use such idea because it could make my architecture very confusing. But, its 真的让我心碎,its great example for seeing things different than the others seeing it. I think in future I could use some of the idea in special cases, tnx) Bad thing, as I remember, that vs and resharper ignores aliases (and some of the developers too) - for example they cant 去为他们定义。而且一般来说,别名非常令人困惑——你不会在那里找到它是什么类,它在做什么
      猜你喜欢
      • 2015-12-06
      • 2021-04-29
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 2013-02-23
      • 2021-08-23
      • 2015-04-01
      • 2011-04-09
      相关资源
      最近更新 更多