是否可以在类中构造函数,使某些函数只能通过预先编写的标识符进行访问?
我会试着用一个(可怜的)例子让我的问题变得更清楚;-)我的班级车有驱动功能,openDoor,closeDoor,startEngine等等。但是,要保持清晰,我想访问这些功能:
car.drive()
car.door.open()
car.door.close()
car.engine.start()
我尝试使用结构和嵌套类,但我不认为这些是正确的方法,因为我不喜欢为我使用的每个“标识符”创建一个对象。
有没有“干净”的方法来做到这一点?
谢谢!
修改 我不确定这是否重要,但还有一些额外的信息:
答案 0 :(得分:3)
嵌套类是正确的方法。
考虑所有Door
个对象都有Open
和Close
个方法,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();
}
}