带有“私有”类的C#中的类修饰符问题

时间:2010-05-13 18:58:37

标签: c# .net private nested-class internal

我有一个有很多方法的课程:

public class MyClass {
    public bool checkConditions() {
        return checkCondition1() &&
               checkCondition2() &&
               checkCondition3();
    }

...conditions methods

    public void DoProcess() {
        FirstPartOfProcess();
        SecondPartOfProcess();
        ThirdPartOfProcess();
    }

...process methods
}

我确定了两个“重要”的工作区域,并决定将这些方法提取到自己的类中:

public class MyClass {
    private readonly MyClassConditions _conditions = new ...;
    private readonly MyClassProcessExecution = new ...;

    public bool checkConditions() {
        return _conditions.checkConditions();
    }

    public void DoProcess() {
        _process.DoProcess();
    }
}

在Java中,我将MyClassConditionsMyClassProcessExecution定义为package protected,但我不能在C#中这样做。


你会如何在C#中做到这一点?

将这两个类设置为MyClass的内部类?

我有2个选项:我要么在MyClass内定义它们,要么在同一个文件中包含所有内容,这看起来令人困惑和丑陋,或者我可以将MyClass定义为partial classMyClass的一个文件,MyClassConditions的其他文件和MyClassProcessExecution的其他文件。

将它们定义为内部?

我真的不喜欢那么多的内部修饰符,因为我没有发现这些类为我的程序/程序集的其余部分添加任何值,并且如果可能的话我想隐藏它们。这并不是说它们在程序的任何其他部分都是有用的/可重用的。

将它们公之于众?

我看不出原因,但我已经在这里选择了这个选项。

还有其他吗?

命名!

由于

5 个答案:

答案 0 :(得分:2)

对于不会在当前程序集之外使用的“Helper”类型类,如果多个类将使用这些方法,则Internal是可行的方法。

对于仅由单个类使用的方法,我只是将它们设置为类的私有,或者如果它实际上是一个在其他地方没有使用的类,则使用内部类。如果代码不依赖于类的任何(非静态)成员,也可以将代码分解为静态方法。

答案 1 :(得分:2)

您最好的选择可能是使用部分类,并将三个代码块放在单独的文件中,添加到同一个类中。然后,您可以将条件和流程代码设为私有,以便只有类本身才能访问它们。

答案 2 :(得分:1)

  

我可以   将MyClass定义为部分类,   有一个文件为MyClass,另一个为   MyClassConditions等   MyClassProcessExecution。

也许这是我的C ++背景,但这是我的标准方法,尽管我将小助手类一起捆绑到一个文件中。

因此,在我目前的一个项目中,Product课程分为Product.csProductPrivate.cs

答案 3 :(得分:1)

我正在寻找其他东西 - 公共/受保护/私有的问题可能无法由此专门解决,但我认为它更适合维护,然后是很多嵌套的内部类。

因为听起来你在顺序算法中有一组步骤,其中一步的执行可能或可能不依赖于前一步的执行。这种类型的顺序步骤处理有时可以使用Chain of Responsibility模式,尽管它从其初始意图稍微变形。仅关注您的“处理方法”,例如,从以下内容开始:

class LargeClass
{
public void DoProcess()
{
  if (DoProcess1())
  {
    if (DoProcess2())
    {
      DoProcess3();
    }
  }
}

protected bool DoProcess1()
{
...
}

protected bool DoProcess2()
{
...
}

protected bool DoProcess3()
{
...
}

}

使用责任链,可以将其分解为每个步骤的一组具体类,这些类继承自一些抽象的步骤类。如果满足必要的前提条件,抽象步骤类更负责确保调用下一步。

public class AbstractStep
{
    public AbstractStep NextStep { get; set; }

    public virtual bool ExecuteStep
    {
       if (NextStep != null)
       {
         return NextStep.ExecuteStep();
       }
    }  
}

public class ConcreteStep1 : AbstractStep
{
    public bool ExecuteStep
    {
       // execute DoProcess1 stuff
       // call base
       return base.ExecuteStep();
    }
}

...

public class ConcreteStep3 : AbstractStep
{
     public bool ExecuteStep
     { 
        // Execute DoProcess3 stuff
        // call base
        return true; // or false?
      }
}

要进行此设置,您可以在代码的某些部分执行以下操作:

var stepOne = new ConcreteStep1();
var stepTwo = new ConcreteStep2();
var stepThree = new ConcreteStep3();
stepOne.NextStep = stepTwo;
stepTwo.NextStep = stepThree;

bool success = stepOne.ExecuteStep();

这可能有助于清理你在单个类中获得的代码膨胀 - 我过去曾将它用于一些顺序类型算法,它帮助很好地隔离了每一步。显然,您可以将相同的想法应用于条件检查(如果适用,则将它们构建到每个步骤中)。您还可以通过让ExecuteStep方法获取某种状态对象的参数,在步骤之间传递状态来对此进行一些修改。

当然,如果你在这篇文章中真正关心的只是隐藏了各个步骤,那么是的,你可以让你的每个子步骤成为你班级中受保护的类来创建步骤。除非您以某种形式或方式向您的客户公开您的库,并且您不希望它们对您的执行步骤有任何类型的可见性,否则这似乎是一个较小的问题,然后使代码可维护。

答案 4 :(得分:0)

使用与重构方法相同的访问修饰符创建类。当您有多个人或自动生成的代码生成工具经常修改相同的类时,部分类才真正有用。他们只是真的避免源代码合并地狱,因为它无法将多个编辑内容合并到同一个文件中,因为它无法将多个编辑合并到同一个文件中。