9.12 对象初始化列表
使用对象初始化列表是一种初始化对象数据的快捷方式。使用对象初始化列表可以在创建对象时,向对象的任何可访问的字段或属性分配值,而无须显式调用构造函数。接下来看一个示例,先声明一个类Car,它具有若干属性和若干公共字段,如代码清单9-36所示。
代码清单9-36 Car类
class Car
{
//私有字段
private string name;
//公共字段
public string produceDate;
//实例构造函数
public Car()
{
System.Console.WriteLine(“实例构造函数调用了!”);
name="Polo";
}
//属性
public string Name
{
get
{
return name;
}
set
{
name=value;
}
}
//自动实现的属性
public string Model{get;set;}
}
由于我们想要测试的是为对象快捷赋值,因此我们设计了这样一个仅有数据成员的类Car。接下来,我们分析下,如果想要在初始化Car类的同时初始化Car类中的某些数据字段,有两种解决方案可行,第一种方案是提供一个带参数构造函数,类似这样:
//带参数的构造函数,可以为类的属性或公共字段提供初始值
public Car(string_name,string_model,string_produceDate)
{
Name=_name;
Model=_model;
produceDate=_produceDate;
}
甚至,我们还可以学以致用,使用在第8章讲过的命名和可选参数特性,如:
//_produceDate参数是可选的,因为它具有默认值
public Car(string_name,string_model,string_produceDate="2010-1-2")
{
Name=_name;
Model=_model;
produceDate=_produceDate;
}
然后,像下面的代码这样对Car类进行实例化:
class ClassExample
{
static void Main()
{
//使用构造函数对公共字段或属性进行初始化
Car car=new Car("Benz","S600","2010-5-1");
//省略了_produceDate参数,因为它有默认值
Car car2=new Car("BMW","760i");
System.Console.WriteLine(car.Name);
System.Console.WriteLine(car2.Name);
}
}
第一种方案有一个特点:都必须提供一个或多个构造函数。
第二种方案是使用我们现在要讲的“对象初始化列表”。上面的示例,我们还可以这样写:
class ClassExample
{
static void Main()
{
//使用对象初始化列表表达式进行初始化
//方法很简单,将()换为{},在里面为每个属性或公共字段赋值,以逗号分隔即可
Car car=new Car{Name="Benz",Model="S600",produceDate="2010-1-1"};
//可以灵活、有选择地对某些属性进行初始化
Car car2=new Car{Name="BMW",Model="760i"};
Car car3=new Car{Name="Cadillac"};
System.Console.WriteLine(car.Name);
System.Console.WriteLine(car2.Name);
System.Console.WriteLine(car3.Name);
}
}
可见,第二种方案使得代码更加紧凑和易读,还省略了编写若干个构造函数的工作量。需要注意的是,对象初始化列表只是简化了这样一个过程,实际上它和下列代码是等价的:
Car car=new Car();
car.Name="Benz";
car.Model="S600";
car.produceDate="2010-1-1";
因此,在使用对象初始化列表的时候,仍然会先调用对象的实例构造函数(不带参数的,默认构造函数),下一章我们还会专门研究对象初始化的顺序。可以从运行结果印证这一点:
实例构造函数调用了!
实例构造函数调用了!
实例构造函数调用了!
Benz
BWM
Cadillac