我有一个汽车类:
public class Car
{
private String _Brand;
private String _Model;
private Engine _Engine;
public Car(){
}
public String Brand
{
get { return _Brand; }
set { _Brand = value; }
}
public String Model
{
get { return _Model; }
set { _Model = value; }
}
public Engine Engine
{
get { return _Engine; }
set { _Engine = value; }
}
}
和引擎类:
public class Engine
{
private int _Code;
private DateTime _Year;
public Engine(){
}
public int Code
{
get { return _Code; }
set { _Code = value; }
}
public DateTime Year
{
get { return _Year; }
set { _Year = value; }
}
}
从 Registration.aspx.cs 的代码隐藏中,我想创建一个按钮,一个汽车和一个引擎与他们各自的关系(组成)。
然而,我对这些物体的构图应如何表现存在巨大的困惑。 IE,如果我必须在Car的构造函数中声明:Engine = new Engine();
或者在注册事件(Button,Code-Behind)中声明:Car car = new Car()
然后car.Engine = new Engine();
,我无法理解。 / p>
我不知道组合关系如何在这样的场景中起作用。宣称“new
”的存在使我陷入混合的概念之中。
此致
答案 0 :(得分:1)
您可以像下面那样重构一下您的课程,以避免boilerplate code。我们只使用名为自动实现属性的功能。
public class Engine
{
public int Code { get; set; }
public DateTime Year { get; set; }
}
public class Car
{
public string Brand { get; set; }
public string Model { get; set; }
public Engine Engine {get; set; }
}
现在请注意已删除了多少行代码。
关于您的问题,您可以使用对象初始值设定项创建类型为Car
的对象,如下所示:
var car = new Car
{
Brand = "the brand name";
Model = "the model name";
Engine = new Engine
{
Code = "the code engine";
Year = new DateTime(2017,1,1); // the year the engine manufactured.
}
}
我建议你阅读这两个功能,自动实现的属性和对象初始化程序。下面是关于这些功能的两个链接。
答案 1 :(得分:0)
我已经讨论了这个级别的课堂架构几年了,所以我会尝试不要听起来很愚蠢:)
首先,我不认为我们在这里谈论作文:(在现实生活中)Engine
的生命周期不受Car
的约束/控制。如果我正确地假设,这两个类都试图代表现实生活的映射。
据我所知,实际上,您可以购买Engine
到Car
,但Car
无法正常运行(但可以存在){ {1}}(也许那些新奇的特斯拉可以吗?)。
这种尖叫不是一种作品,因为它没有描述所有权关系。
根据您想要的严格程度,我称之为聚合(更多)或协会(更少)。
我个人更倾向于聚合,因为这是一种更强大的关系,比如,Engine
和Car
。
所以,为此,我的建议是:
<强> C#强>
Spoiler
<强>代码隐藏强>
public class Engine
{
public Engine() { ... }
public int Code { get; set; }
public DateTime Year { get; set; }
}
public class Car
{
public Car(Engine engine) : this() {
this.Engine = engine;
}
public Car() {
}
public string Brand { get; set; }
public String Model { get; set; }
public Engine Engine { get; set; }
}
该var engine = new Engine();
var car = new Car(engine);
类定义表示您可以使用或不使用Car
创建Car
,但对我而言,它强调Engine
对于Engine
确实很重要Car
,因此可以使用接受Engine
的构造函数。
关于作文
Car
的组成是&#34;整体&#34; Engine
是&#34;部分&#34;表示Engine
生命周期完全由Car
控制。在这种情况下,您基本上声明&#34;在创建Car的新对象时,该对象将在内部创建一个新引擎,该引擎将在不再使用Car对象时进行处理。&#34;
该代码如下所示:
//still the same
public class Engine
{
public Engine() { ... }
public int Code { get; set; }
public DateTime Year { get; set; }
}
public class Car
{
public Car() {
//_engine = new Engine();
}
//Engine initialisation can be either here or inside the constructor (check constructor's commented code)
private readonly Engine _engine = new Engine();
public string Brand { get; set; }
public String Model { get; set; }
//you shouldn't be able to assign an _engine from outside
public Engine Engine { get { return _engine; } }
}
撰写代码隐藏
var car = new Car();
car.Engine.Code = 123;
答案 2 :(得分:0)
这一切都取决于你设计课程的方式。汽车和发动机非常通用。例如,如果您要创建梅赛德斯,那么创建一个继承自 Car 的新类型 MercedesCar 是有意义的。在这种情况下,您可以在 MercedesCar 的构造函数中实例化 MercedesEngine ,如下所示:
json_decode_pipeline
但如果你只是坚持使用 Car 课程,那么从外面创建引擎并没有错!
答案 3 :(得分:0)
这取决于您希望控件如何访问Engine属性的可访问性。
案例1: 如果您希望Car完全控制Engine属性而没有其他人访问它,请将其设置为私有字段并在Car构造函数中实例化。
public class Car
{
private readonly Engine _engine;
public Car()
{
_engine = new Engine();
}
}
案例2: 应该可以从外部访问引擎,以便任何人都可以设置或访问引擎。 它可以通过两种方式完成:
1)构造函数注入 - 通过构造函数注入依赖项,通常使用接口进行抽象,以便轻松完成模拟/单元测试。
public class Car
{
public Car(IEngine engine)
{
Engine = engine;
}
public IEngine Engine { get; set; }
}
var car = new Car(new Engine());
2)手动设置引擎属性
public class Car
{
public Engine Engine { get; set; }
}
var car = new Car();
car.Engine = new Engine();