不能不说的C#特性-对象集合初始化器
系列文章导航:
不能不说的C#特性-迭代器(下),yield以及流的延迟计算
走进Linq-Linq to SQL How do I(1)
走进Linq-Linq to SQL How do I(2)
走进Linq-Linq to SQL How do I(3)
走进Linq-Linq to SQL源代码赏析 Table
走进Linq-Linq to SQL源代码赏析之Provider的初始化
走进Linq-Linq to SQL源代码赏析,通过Linq to SQL看Linq
在写一些实体类的时候,我们往往在写构造方法的时候思考很长时间,除了一个无参构造器外还在想需要写几个构造器呢?哪些参数是需要初始化的。现在你再也不需要为这事烦恼了。C# 3.0为你提供了对象集合初始化器:
///
/// 图书类
///
public class Book
{
///
/// 图书名称
///
public string Title { get; set; }
///
/// 单价
///
public float Price { get; set; }
///
/// 作者
///
public string Author { get; set; }
///
/// ISBN号
///
public string ISBN { get; set; }
}
//对象初始化器
Book book = new Book { Title="Inside COM",ISBN="123-456-789"};
/// 图书类
///
public class Book
{
///
/// 图书名称
///
public string Title { get; set; }
///
/// 单价
///
public float Price { get; set; }
///
/// 作者
///
public string Author { get; set; }
///
/// ISBN号
///
public string ISBN { get; set; }
}
//对象初始化器
Book book = new Book { Title="Inside COM",ISBN="123-456-789"};
现在你想初始化几个就初始化几个,不需要出现这种情况:















这一串的构造方法都是为了应付不同的初始化情况。好了,来看看对象初始化器编译器在后面为我们做了些什么呢? 使用Reflector反编译程序集:
Book <>g__initLocal0 = new Book();
<>g__initLocal0.Title = "Inside COM";
<>g__initLocal0.ISBN = "123-456-789";
Book book = <>g__initLocal0;
<>g__initLocal0.Title = "Inside COM";
<>g__initLocal0.ISBN = "123-456-789";
Book book = <>g__initLocal0;
C#编译器生成了一个新的局部变量<>g__initLocal0,调用Book的默认无参构造方法初始化它,然后对它的属性进行赋值,最后将这个局部变量赋值给book。看到这里,我们应该想到,要使用对象初始化器,那么这个对象必须有一个无参构造方法,如果你给这个方法写了一个有参构造方法而将它的默认无参构造方法覆盖了并且没有提供一个新的无参构造方法,那么使用对象初始化器编译的时候是不会通过的(不过想不通,为啥C#编译器生成这么一个奇怪的局部变量名字,还有为啥不直接使用book呢)。像下面的代码不更好:
Book book = new Book();
book.Title = "Inside COM";
book.ISBN = "123-456-789";
book.Title = "Inside COM";
book.ISBN = "123-456-789";
后来我发现我是在debug模式下编译的,换到release模式下变成了这样:
Book <>g__initLocal0 = new Book();
<>g__initLocal0.Title = "Inside COM";
<>g__initLocal0.ISBN = "123-456-789";
<>g__initLocal0.Title = "Inside COM";
<>g__initLocal0.ISBN = "123-456-789";
[第1页][第2页]