代码改变世界

CLR via C# 边读边想 10 - 属性

2012-07-06 15:27  richardzhaoxb  阅读(118)  评论(0编辑  收藏  举报

Parameterless Properties

属性的基本知识就不再累述了,这里谈谈自动实现的属性: 

public sealed class Employee {
    // This property is an automatically implemented property
    public String Name { get; set; }
}

C# 编译器会自动生成生成一个成员字段,那有人可能就有疑问了,这样的属性和直接公开字段有什么不同。还是有不同的,如果以后对这个字段的访问和赋值有特殊的逻辑,改了这个属性的实现,调用方还是不用改代码,而直接访问字段就做不到这一点。

但是自动实现的属性有下面几个问题:

自动生成的字段成员的名字,每次编译可能都不一样的,这对于要实现 序列化/反序列化 的类来说就有风险了。 所以对于要被 序列化/反序列化 的类,一定不要用自动实现的属性。

对于自动实现的属性的set 和 get 方法,不能在调试时设置断点。

自动实现的属性必须同时提供 set 和 get 方法,就不能实现 read only / write only 的效果。

 

Object and Collection Initializers

C# 的新版本提供了初始化对象以及赋值的新语法:

Employee e = new Employee() { Name = "Jeff", Age = 45 };

上面的代码先调用无参构造函数,然后给两个属性赋值。对于集合属性可以这样初始化赋值:

Classroom classroom = new Classroom {
    Students = { "Jeff", "Kristin", "Aidan", "Grant" }
};

 

Anonymous Types

C# 允许很方便的使用匿名类型:

// Define a type, construct an instance of it, & initialize its properties
var o1 = new { Name = "Jeff", Year = 1964 };

赋的值也可以是变量:

1 String Name = "Grant";
2 DateTime dt = DateTime.Now;
3 // Anonymous type with two properties
4 // 1. String Name property set to Grant
5 // 2. Int32 Year property set to the year inside the dt
6 var o2 = new { Name, dt.Year };

编译器对于匿名类型的自动识别是很智能的,如果发现多个匿名类型的结构是一样的,它只会定义一个匿名类型。

LINQ中大量使用匿名类型的特性。

 

Parameterful Properties

就是可以通过 index 访问的属性,很少自己定义,用到时再来参考。

 

Property Accessor Accessibility

属性的 get 和 set 可以用不同的访问修饰符,一般推荐get用 public的,set用 protected的。 

 

Generic Property Accessor Methods 

虽然 属性最终是用方法实现的,方法支持泛型方法,但是属性不支持。 如果要使用泛型,那你只能用方法了。