屬性是一種成員,它提供靈活的機制來讀取、寫入或計算私有字段的值。 屬性可用作公共數據成員,但它們實際上是稱為“訪問器”的特殊方法。 這使得可以輕松訪問數據,還有助於提高方法的安全性和靈活性。
一個簡單的示例:
public class Person
{
private string _name = "No one";
public Person(string name)
{
_name = name;
}
public string Name
{
get { return _name;}
}
};
用法:
Person p = new Person ("Arya");
System.Console.WriteLine (p.Name);
這里Name是一個只讀的屬性,如果要給Name賦值,那么就會報錯。
那么就需要在Name里添加set訪問器
public string Name
{
get { return _name;}
set { _name = value;}
}
value是set訪問器的隱式參數,此參數的類型是屬性的類型(string)。
用法:
p.Name = "Erya";
索引器允許類或結構的實例就像數組一樣進行索引。 索引器類似於屬性,不同之處在於它們的取值函數采用參數。
在Person類里添加一個索引器:
public string this[string key]
{
get { if (key == "Name")
return _name;
return null;}
set { if (key == "Name")
_name = value;
return;}
}
跟屬性一樣,索引器可以只有set訪問器或者get訪問器,或者二者都有,不過,索引器可輸入參數。
用法:
p ["Name"] = "Anonymous";
System.Console.WriteLine (p ["Name"]);
屬性和索引器的區別:
屬性 |
索引器 |
---|---|
允許像調用公共數據成員一樣調用方法。 |
允許對一個對象本身使用數組表示法來訪問該對象內部集合中的元素。 |
可通過簡單的名稱進行訪問。 |
可通過索引器進行訪問。 |
可以為靜態成員或實例成員。 |
必須為實例成員。 |
屬性的 get 訪問器沒有參數。 |
索引器的 get 訪問器具有與索引器相同的形參表。 |
屬性的 set 訪問器包含隱式 value 參數。 |
除了value參數外,索引器的 set 訪問器還具有與索引器相同的形參表。 |
支持對自動實現的屬性使用短語法。 |
不支持短語法。 |
所謂自動實現屬性的短語法,就是一個屬性可以寫成下面這種方式:
public int Age { get;set;}
而這種寫法妙用就在於可以寫成這樣:
public int Age { get;private set;}
即對外只讀,對內可寫。
或者
protected int RealAge{ private get; set;}
即對自己或派生類可寫,對自己可讀。
對於屬性和索引器,get和set至少要有一個不添加訪問修飾符,可訪問性與自身相同,而另一個可以添加低於自身的訪問修飾符。
接着為Person添加一個派生類:
public class Coder : Person
{
public new int Age {get{ return 10;}}
public new string this[string key]
{
get {if (key == "Name")
return "I don't know.";
return null;}
}
}
這里我們使用new關鍵字聲明了一個同名的屬性Age和同名的索引器。當我們調用這個屬性和索引器時:
Coder c = new Coder();
System.Console.WriteLine (c.Age);
System.Console.WriteLine (c["Name"]);
會顯示10和I don't know.
當然我們也可以時間倒流並找回自己的名字。
System.Console.WriteLine (((Person)c).Age);
System.Console.WriteLine (((Person)c)["Name"]);
顯示0和No one。
既然有了派生類,我們就可以寫虛屬性和虛索引器了。
例如在Person里添加:
public virtual bool Male {
get;
set;
}
public virtual bool this[bool noSense]
{
get { return noSense;}
}
在Coder里面添加
public override bool Male
{
get { return true;}
set { }
}
public override bool this[bool noSense]
{
get { return !noSense;}
}
注意:在重寫屬性或索引器時,被重寫的訪問器對重寫代碼而言,必須是可訪問的。此外,屬性或索引器和訪問器的可訪問性級別都必須與相應的被重寫屬性或索引器和訪問器匹配。
重寫虛屬性或索引器的屬性還可以是 sealed 的,這表示它對派生類不再是虛擬的。並且,可以將抽象類的屬性或索引器聲明為 abstract。這意味着類中沒有任何實現,派生類必須編寫自己的實現。
說了這么多,發現屬性和索引器有很多相似的地方,那么就再加點不一樣的。
例如:
static public string Planet
{
get { return "The Earth";}
}
索引器無法是靜態成員。
再例如:
public int this[int a, int b]
{
get { return a + b;}
}
索引器可以有多個參數(屬性連一個參數都沒有……),參數類型也不受限於int和string。
最后補一發訪問修飾符:
public
同一程序集中的任何其他代碼或引用該程序集的其他程序集都可以訪問該類型或成員。
private
只有同一類或結構中的代碼可以訪問該類型或成員。
protected
只有同一類或結構或者此類的派生類中的代碼才可以訪問的類型或成員。
internal同一程序集中的任何代碼都可以訪問該類型或成員,但其他程序集中的代碼不可以。
protected internal
由其聲明的程序集或另一個程序集派生的類中任何代碼都可訪問的類型或成員。 從另一個程序集進行訪問必須在類聲明中發生,該類聲明派生自其中聲明受保護的內部元素的類,並且必須通過派生的類類型的實例發生。
關於數組的屬性測試:
public class ArrayAttributeTest { public byte[] buffer { get; private set; } public byte[] buffer1; public ArrayAttributeTest() { buffer = new byte[10]; buffer1 = new byte[10]; } } static void Main(string[] args) { ArrayAttributeTest test = new ArrayAttributeTest(); test.buffer[0] = 1; //不會報錯 test.buffer[1] = 2; //test.buffer = test.buffer1; //這句會報錯

}
將buffer數組設置為對外可讀對內可寫,測試表明外部可以對數組元素賦值但是不能賦值為另外一個數組
文章轉載自:https://blog.csdn.net/ecidevilin/article/details/52525080