代码之家  ›  专栏  ›  技术社区  ›  Archeg

你能在C中创建私有类吗?

  •  23
  • Archeg  · 技术社区  · 16 年前

    对于.NET哲学家来说,这是一个问题:

    据我所知,微软有意识地拒绝使用C中的私有类。他们为什么这么做?他们的理由是什么?

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

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

    在“private class”后面,我指的是不能在任何其他名称空间中使用的类,除了它自己的。

    我的问题不是-我怎么能模仿这个,或者用另一种方式。我只是想知道,为什么不在没有任何父类的类关键字中使用private关键字呢?我想应该有原因,我想知道

    6 回复  |  直到 11 年前
        1
  •  15
  •   Jordão    11 年前

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

    而不是使用 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 内部代码 福 .

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

    using MyCompany;
    
    // ...
    
    var baz = new Foo.Baz();
    

    这可以通过为类使用别名来减轻:

    using Baz = MyCompany.Foo.Baz;
    
    // ...
    
    var baz = new Baz();
    

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

    更新

    有趣的是,C 6将 static using statements ,这可以有效地改进此建议以使用 公共静态分部类 作为一个“模块”。您只需使用“模块”直接访问其类型。

    希望它能像这样工作:

    using MyCompany.Foo;
    
    // ...
    
    var baz = new Baz();
    

    就好像 福 是命名空间。

        2
  •  21
  •   Alex Humphrey    16 年前

    允许类对名称空间是私有的将不会达到有意义的保护级别。

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

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

        3
  •  11
  •   Richard    16 年前

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

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

    和 Inner 仅对的成员可见 Outer .

    在最外层(即命名空间中) private 按照它的定义是没有意义的(因为里面没有私密的东西)。代替使用 internal (仅对包含程序集的成员可见)。

        4
  •  2
  •   Rowland Shaw    16 年前

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

    如果希望类只在特定程序集中可见(dll/exe/etc),则应将其声明为 internal ( Friend 在VB中)

        5
  •  1
  •   Preet Sangha    16 年前

    是的,但是您可以通过内部类和 internalsvisibletoAttribute 如果命名空间跨多个程序集拆分。

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

        6
  •  1
  •   Community Mohan Dere    9 年前

    所以我想你想这么做

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

    如果是的话。那么foo将服务于什么目的呢?在命名空间中,您可以比内部更严格地使用该类,如果我可以这样做,我将在何处使用它。

    这就是为什么要进行编译时验证的原因。

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

    推荐文章