9

具体来说,谁能给我具体的例子,说明何时或何时不使用嵌套类?

我从很久以前就知道这个功能,但从来没有理由使用它。

谢谢。

4

9 回答 9

16

当嵌套类仅由外部类使用时,不再需要的一个很好的示例是用于集合的枚举器类。

另一个示例可能是枚举替换类中方法使用的真假参数,以澄清调用签名......

代替

public class Product
{
    public void AmountInInventory(int warehouseId, bool includeReturns)
    {
        int totalCount = CountOfNewItems();
        if (includeReturns)
            totalCount+= CountOfReturnedItems();
        return totalCount;
    }
}

  product P = new Product();
  int TotalInventory = P.AmountInInventory(123, true);  

这使得不清楚“真实”是什么意思,你可以写:

public class Product
{
    [Flags]public enum Include{None=0, New=1, Returns=2, All=3 }
    public void AmountInInventory(int warehouseId, Include include)
    {
        int totalCount = 0;
        if ((include & Include.New) == Include.New)
            totalCount += CountOfNewItems();
        if ((include & Include.Returns) == Include.Returns)
            totalCount += CountOfReturns();
        return totalCount;
    }
}


  product P = new Product();
  int TotalInventory = P.AmountInInventory(123, Product.Include.All);  

这使得客户端代码中的参数值清晰。

于 2009-09-15T15:44:20.427 回答
11

我使用嵌套类的两个地方:

  • 嵌套类仅由外部类使用,我想要完全私有的范围。

  • 嵌套类专门用于实现在别处定义的接口。例如,实现一个枚举器就属于这一类。

于 2009-09-15T15:46:16.367 回答
4

当您确定嵌套类在其他任何地方使用它没有意义时,您真的只想使用嵌套类。

例如,如果您需要在短时间内创建与该组对象相关的函数和成员信息(如方法或属性)的几种对象类型的列表,则可以使用嵌套类来执行此操作。也许您需要创建一个包含某种类型对象的所有组合的列表,然后标记所有具有某种属性的组合。这对于嵌套类来说是一个很好的例子。

如果您不需要嵌套类上的方法,您可能只使用一个结构,但我不知道 IL 是否以不同的方式对待它们。

于 2009-09-15T15:50:44.627 回答
3

我有时将它用于父类内部的一个或两个函数所需的简单辅助类。

于 2009-09-15T15:46:28.580 回答
3

对于一个实际示例,请参阅今天早上早些时候提出的这个问题:
使同一程序集中的一个对象只能被另一个对象访问?

摘要:您可以在其业务对象中嵌套关联的数据类。

于 2009-09-15T15:47:41.543 回答
2

我见过嵌套类的情况,即仅在一个类中使用特殊用途的数据结构,或者仅在一个类中引发并捕获某个异常。

于 2009-09-15T15:45:51.250 回答
1

当我有一个不需要对系统中的任何其他对象可见的辅助类时,我会嵌套类。这使可见性尽可能受到限制,这有助于防止对类的意外使用

于 2009-09-15T15:48:52.367 回答
1

遵循 Uncle Bob 的内聚“规则”应该会发现您实际上创建了相当多的嵌套(并且嵌套,嵌套!)类。这些可以设为非嵌套,但前提您现在有其他客户端引用它们。

于 2009-09-15T15:54:05.803 回答
1

我想改进我以前的答案!

我经常使用嵌套类的一个特定领域是启用接口注入和控制反转。例子...

public class Worker
{
  private IHelper _helper;

  public Worker()
    : this (new DefaultHelper())
  {
  }
  public Worker(IHelper helper)
  {
    this._helper = helper;
  }

  private class DefaultHelper : IHelper
  {
  }
}
于 2009-09-15T16:00:41.953 回答