类中的函数的分层结构(C#)

时间:2012-01-13 10:23:00

标签: c# function structure

是否可以在类中构造函数,使某些函数只能通过预先编写的标识符进行访问?

我会试着用一个(可怜的)例子让我的问题变得更清楚;-)我的班级车有驱动功能,openDoor,closeDoor,startEngine等等。但是,要保持清晰,我想访问这些功能:

car.drive()
car.door.open()
car.door.close()
car.engine.start()

我尝试使用结构和嵌套类,但我不认为这些是正确的方法,因为我不喜欢为我使用的每个“标识符”创建一个对象。

有没有“干净”的方法来做到这一点?

谢谢!

修改 我不确定这是否重要,但还有一些额外的信息:

  • “Car”-Class是Singelton
  • 除了功能之外,引擎,车门或我车的任何其他部分都没有任何其他属性(耶。真是可怜的例子!)

4 个答案:

答案 0 :(得分:3)

嵌套类是正确的方法。

考虑所有Door个对象都有OpenClose个方法,Car个对象会有Door个对象的多个实例(2,也许4,甚至更多。)

同样,每个Car对象都有一个Engine对象的实例,可以是Start ed,Stop ped,并且更换了油({{ 1}})。

然后,这些类中的每一个都可以在ChangeOil类之外进行扩展。如果您想要更改Car类内的部分代码,所有Door对象Car会自动继承这些更改。如果你想用更强大的引擎替换汽车引擎,你可以通过将Door对象的新实例传递给Engine对象来轻松实现。

可以以与使用类相同的方式使用结构,但通常你应该选择使用类而不是结构。应该为应该具有值类型语义的类型保留结构,即,小,不可变等。有关差异以及如何做出明智决定的更多信息,请参阅this question

为了防止我说服嵌套类是正确的方法,我将最后指出它们也是实现你想要的唯一方法。也就是说,除了hacky解决方案之外,例如在每个函数名称的开头附加伪命名空间(即Car),这很丑陋并且根本不会让你获得任何东西。

答案 1 :(得分:1)

不 - 您需要拥有自己的方法的嵌套类门。您可以将描述符添加到方法名称中。所以你会有

car.DoorOpen();
car.DoorClose();

我会上课,因为你可能拥有的课程适用于课堂门而不是汽车。并将车门的属性添加到汽车中。

car.Door.Open();

答案 2 :(得分:1)

此处不需要嵌套类,对于任何理解困难的人,以下是嵌套类方法:

public class Car
{
    public static Car Instance { get; private set; }
    static Car() { Car.Instance = new Car(); }
    private Car() { }
    public static class Door
    {
        public static void Close()
        {
            /* do something with Car.Instance */
        } 
    }
}

使用静态类会产生以下语法:

Car.Door.Close();

C#允许您嵌套类定义,它没有像其他语言那样的“内部类型”或“内部类”的正式概念。

这是组件建模/设计不佳的一个很好的例子。

考虑以下问题,这是一个更容易接受和更优雅的解决方案:

public interface ICar
{
    IDoor Door { get; set; } 
}

public class Car : ICar
{
    public IDoor Door { get; set; }
}

public interface IDoor
{
    void Open();
    void Close();
}

public class Door : IDoor
{
    public override void Open() { /* do something */ }
    public override void Close() { /* do something */ }
}

以上可以使用C#的初始化语法:

var car = new Car
{
    Door = new Door()
};

car.Door.Open();

如果您的抱怨不断需要输入“new XYZ”,您还可以将初始化烘焙到构造函数中。用“穷人”DI模式正确完成它应该是这样的:

public class Car : ICar
{
    public IDoor Door { get; set; }
    public Car()
        : this(new Door())
    {
    }
    public Car(IDoor door)
    {
        this.Door = door;
    }
}

这避免了在创建过程中执行初始化的需要,并允许您将新的/不同的Door类型注入堆栈。

var common = new Car();
var lambo = new Car(new LamboDoor());

在任何一种情况下,调用代码看起来都是一样的:

common.Door.Open();
lambo.Door.Open();

最后,您可以考虑使用Composition或DI框架,而不是将new()运算符烘焙到您的实现代码中。在任何情况下,最合适的方法是使用属性并构造表达您的意图的合法对象模型。嵌套类型不会产生你正在寻找的语法,除非使用静态成员并且采用这种方法很少是一个好主意,我只看到它用于简单的单例实现,当然从未用于API / Framework / Model定义。 / p>

答案 3 :(得分:0)

只是我的2感。

我喜欢@Code Gray嵌套类的想法。但是为了达到调用方法的正确顺序,我认为你需要在驱动程序下嵌套汽车。司机会做这样的事情。

public class Driver
{
   public void Drive(Car car)
   {
      car.drive();
      car.door.open();
      car.door.close();
      car.engine.start();
   }
}