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