在學齡前學習c#的過程中,經常遇到這樣的語句:
public string StudentName
{
get{return stuName;}
set{stuName=value;}
}
當時也不是很明白為什麼要這樣?學深了c#後,又沒法對其做一個總結。今天看了《Visual c#.net程式設計教程》這本書,總結得不錯,做下筆記:在許多物件導向程式設計語言中,屬性 { Student stu = new Student(); Console.Write(stu.StudentName); Console.ReadKey(); } } }
上面代碼中定義了一個屬性StudentName,它包含get訪問器和set訪問器。屬性StudentName封裝了類Student中的欄位stuName,欄位如果沒有加存取控制符,被預設為private,外界不能直接存取它,現在外界可以通過StudentNamee屬性自由地存取 stuName欄位了。
屬性的get和set都是可執行檔程式語句組合,具有行為的特點;而使用具有get訪問器和set訪問器的屬性時候就像使用欄位一樣,即可以作為左值接受資料,又可以作為右值輸出資料,系統正是按照屬性出現在語句中的位置,自動地選擇是調用get還是調用set。
屬性的讀寫控制
屬性中的get和set可以只用一個,如果只有get而沒有set,那麼這個屬性只可讀出,不可寫入;如果只有set而沒有get,那麼這個屬性是唯寫入,不可讀出。
在屬性中完成更多功能
既然get和set是程式,那當然可以做更多的事情。一個合理的分工是:設計欄位是為了便於內部方法使用,而盡量與外界隔絕;設計屬性考慮的是方便外界的使用,但是不讓外界知道的資料一律不給。
具體說明:
set 訪問器與返回 void 的方法類似。它使用稱為 value 的隱式參數,此參數的類型是屬性的類型。在下例中,set 訪問器被添加到Name 屬性:
public string Name { get { return name; } set { name = value; }}
當對屬性賦值時,用提供新值的參數調用 set 訪問器。例如:
e1.Name = "Joe"; // The set accessor is invoked here
在 set 訪問器中對局部變數聲明使用隱式參數名 (value) 是錯誤的。
備忘
屬性按如下方式,根據所使用的訪問器進行分類:
- 只帶有 get 訪問器的屬性稱為唯讀屬性。無法對唯讀屬性賦值。
- 只帶有 set 訪問器的屬性稱為唯寫屬性。唯寫屬性除作為賦值的目標外,無法對其進行引用。
- 同時帶有 get 和 set 訪問器的屬性為讀寫屬性。
在屬性聲明中,get 和 set 訪問器都必須在屬性體的內部聲明。
使用 get 訪問器更改對象的狀態是一種錯誤的編程樣式。例如,以下訪問器在每次訪問 number 欄位時都產生更改對象狀態的副作用。
public int Number { get { return number++; // Don't do this }}
可以將 get 訪問器用於返回欄位值,或用於計算欄位值並將其返回。例如:
public string Name { get { return name != null ? name : "NA"; }}
在上述程式碼片段中,如果不對 Name 屬性賦值,它將傳回值NA。
樣本 1
此例說明如何訪問基類中被衍生類別中具有同一名稱的另一個屬性隱藏的屬性。
// property_hiding.cs
// Property hiding
using System;
public class BaseClass
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
public class DerivedClass : BaseClass
{
private string name;
public new string Name // Notice the use of the new modifier
{
get
{
return name;
}
set
{
name = value;
}
}
}
public class MainClass
{
public static void Main()
{
DerivedClass d1 = new DerivedClass();
d1.Name = "John"; // Derived class property
Console.WriteLine("Name in the derived class is: {0}",d1.Name);
((BaseClass)d1).Name = "Mary"; // Base class property
Console.WriteLine("Name in the base class is: {0}",
((BaseClass)d1).Name);
}
}
輸出
Name in the derived class is: John
Name in the base class is: Mary
以下是上例中顯示的重點:
衍生類別中的屬性 Name 隱藏基類中的屬性 Name。在這種情況下,衍生類別的該屬性聲明使用 new 修飾符:
public new string Name
{
...
轉換 (BaseClass) 用於訪問基類中的隱藏屬性:
((BaseClass)d1).Name = "Mary";