CLR提供两种类型的属性:无参属性和带参属性。前者简单的称为属性,后者在C#中通常称作索引器。
无参属性:
1.通常共有属性和私有字段结合,实现类信息的封装。
2.可把属性看做带逻辑的字段,保证了安全,操作方便。
3.CLR支持实例,静态,抽象和虚属性。
4.可以定义任意访问级别,也可以在接口中定义。
5.无参属性含有一个名称和返回类型(不能为void),不能重载
6.当定义一个属性时,中间代码中实际上还是自动生成对应的get_xx,set_xx方法。对属性的操作,实际上就是对此方法的操作。
7.根据属性定义(只读,还是只写),生成单个set_xx,或者get_xx方法。
{
static void Main()
{ }
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
IL:
{
this.age = value;
}
public int get_Age()
{
return this.age;
}
所以,对于不支持属性的语言,也可以采用这种方式,实现对字段的封装。
8.属性不能作为out/ref传递给方法,字段则可以。
9.如果属性中执行语句过多,要花很多时间,这时候优先选用方法。例如线程同步和Remoting。
10.多次访问属性,每次返回的值可能不同;而字段的值每次返回都不会改变。例如System.DateTime属性——MS以后会将其改为方法。
带参属性
1.有参属性使用this关键字定义。get方法可以接受一个或多个参数,set方法可以接受两个或多个参数。生成的IL中对应方法set_item,get_item.
2.C#中实际上是对[ ]运算符的重载。
{
static void Main()
{
PropertyDemo demo = new PropertyDemo();
Console.WriteLine(demo[1]);
}
int[] arr=new int[]{1,2,3,4};
public int this[int index]
{
set
{
arr[index] = value;
}
get
{
return arr[index];
}
}
}
{
this.arr[index] = value;
}
public int get_Item(int index)
{
return this.arr[index];
}
3.有参属性(索引器)可以重载(不能根据返回类型的不同构成重载)。
{
set { }
}
public int this[double index]
{
set { }
}
4.可以通过特性来改变元数据中索引器的名称
public sealed class BitArray
{
[IndexerName("Bit")]
public bool this[int bitPos]
{
set { }
}
}
这样生成的方法名称就是get_Bit,set_Bit.
5.索引器可以用来定义集合类
http://blog.csdn.net/JustLovePro/archive/2008/07/11/2639510.aspx
性能
1.属性在编译时,内联了其代码,从而减小了运行时方法调用的性能损耗。
2.内联通常在方法代码量不大时进行,并且不能人为nei控制。
3.内联保证了属性运行时和字段具有一样的性能
4.注意一点:由于在debug期没有内联属性方法,release后才真正内联,所以release后的版本要快~
5.字段不受上述影响
属性的访问级别
当我们定义一个属性为public时,实际上定义了get_xx方法为public,set_xx方法为protected.
不支持泛型属性