CLR提供兩種類型的屬性:無參屬性和帶參屬性。前者簡單的稱為屬性,後者在C#中通常稱作索引器。
無參屬性:
1.通常共有屬性和私人欄位結合,實作類別資訊的封裝。
2.可把屬性看做帶邏輯的欄位,保證了安全,操作方便。
3.CLR支援執行個體,靜態,抽象和虛屬性。
4.可以定義任意存取層級,也可以在介面中定義。
5.無參屬性含有一個名稱和傳回型別(不能為void),不能重載
6.當定義一個屬性時,中間代碼中實際上還是自動產生對應的get_xx,set_xx方法。對屬性的操作,實際上就是對此方法的操作。
7.根據屬性定義(唯讀,還是唯寫),產生單個set_xx,或者get_xx方法。
Code
class PropertyDemo
{
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:
Code
public void set_Age(int value)
{
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#中實際上是對[ ]運算子的重載。
Code
class PropertyDemo
{
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];
}
}
}
IL:
Code
public void set_Item(int index, int value)
{
this.arr[index] = value;
}
public int get_Item(int index)
{
return this.arr[index];
}
3.有參屬性(索引器)可以重載(不能根據傳回型別的不同構成重載)。
Code
public int this[int index]
{
set { }
}
public int this[double index]
{
set { }
}
4.可以通過特性來改變中繼資料中索引器的名稱
Code
using System.Runtime.CompilerServices;
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.
不支援泛型屬性