C#封裝:關於欄位屬性的get和set方法的小總結
前提須知: 只有get方法叫只讀屬性,只有set方法叫只寫屬性,兩個方法都存在叫可讀可寫屬性
先看個例子:
// 出於安全性需要,進行封裝欄位,我們把欄位訪問修飾符設成private私有,但是私有欄位我們都知道只能在自己類中呼叫,於是我們就
// 有了屬性這個概念來進行對欄位數值的賦值(set方法)和取值(get方法)
public class Person
{
/* 欄位名我們一般用下劃線開頭 (在有些公司裡也許會統一欄位名開頭小寫的標準) */
public string Name
get { return _name; } /*get方法是對欄位進行取值時呼叫*/
set { _name = value; } /*set方法是對欄位進行賦值時呼叫*/
}
// 也許這時候您會問:這兩個是方法嗎,一般的方法至少是void fun( ){ } 這種吧,你這連個返回值型別和括號都沒有叫什麼函式,請您慢慢往下看
// 下面截圖我們會通過reflector
privatte int _age;
public string Age
{
get { return _age; }
set { _age = value; }
}
private char _sex;
public string Sex;
{
get { return _sex; }
set { _sex = value; }
}
private string _hobby;
public string Hobby
{
get { return _hobby; }
set { _hobby = value; }
}
private string _phone;
public string Phone
{
get { return _hobby; }
set { _hobby = value; }
}
public void show( )
{
Console.WriteLine("我叫{0},今年{1}歲,是個{2}生,興趣是{3},電話是{4}.",this.Name,this.Age,this.Sex,this.Hobby,this.Phone);
}
/****
* 構造一個Person函式,以便於例項化物件時進行傳參.(結合下面)
****/
10行 public Person (string Name, int Age, char Sex, string Hobby, string Phone) /*先寫個很全引數的建構函式,就方便20和30行的簡寫了*/
{
this.Name = Name;
this.Age = Age;
this.Sex = Sex;
this.Hobby = Hobby;
this.Phone = Phone;
}
/* 當我們只想傳遞部分資訊時可以建立多個建構函式,例如:只輸入
姓名,愛好, 號碼時呼叫一個新的建構函式 */
20行 public Person(string Name, string Hobby, string Phone) : this(Name, 0, '男', Hobby, Phone)
{
}
/* 再舉個例子吧------>只輸入姓名,年齡,性別 */
30行 public Person(string Name, int Age, char Sex) : this( Name, Age, Sex, "hobby", "phone") /* 繼承引數最齊全的構造方法後,對自己沒有的引數進行任意賦值 */
{
}
/*****************************************
* 20行程式碼同等與下面程式碼,不過我們發現這樣寫會重複性寫很多多餘的程式碼,所以我們這裡用this關鍵詞寫成20行的形式
* 這樣可以有效的避免重複性操作,所以我建議不去下面這種形式 (我個人認為程式碼能多簡潔就多簡潔)
* public Person (string Name, string Hobby, string Phone )
* {
* this. Name = Name;
* this.Hobby = Hobby;
* this.Phone = Phone;
* }
*****************************************/
// 下面這個用於輸出的方法我就不優化了
public void show()
{
Console.WriteLine("我叫{0},今年{1}歲,是個{2}生,興趣是{3},電話是{4}.",this.Name,this.Age,this.Sex,this.Hobby,this.Phone); / *小黑*/
// Console.WriteLine("我叫{0},興趣是{1},電話是{2}.", this.Name, this.Phone); /*小紅*/
// Console.WriteLine("我叫{0},今年{1}歲,是個{2}生.",this.Name,this.Age,this.Sex ); /*小粉*/
}
class Program
{
static void Main(string[ ] args)
{
/*上面建構函式的好處在於,不需要使用 [物件名].方法名( ) 的形式進行賦值,類在建立一個物件時會先去呼叫類的建構函式*/
Person black = new Person("小黑",17,'男',"遊戲","110"); // 呼叫第10行的建構函式
Person red = new Person("小紅","繪畫","120"); // 呼叫第20行的建構函式
Person pink = new Person("小粉",21,"女"); //呼叫第30行的建構函式
black.show( );
red.show( );
Console.ReadKey( );
}
}
看圖說話 : 通過reflector這個微軟員工寫的反編譯工具,我們可以知道 get; set; 這兩個方法的實際執行程式碼,如上面的Name屬性
我們寫的是:
private string _name;
public string Name
{get { return _name; } /*get方法是對欄位進行取值時呼叫*/
set { _name = value; } /*set方法是對欄位進行賦值時呼叫*/
}
通過反編譯我們可以知道它的本質程式碼是:
public string get_Name( )
{
return this._name; /*get方法返回的其實是欄位*/
}
public void set_Name( string value ) /*
這裡接收了物件例項化時呼叫建構函式的引數 */
{
this._name = value; /*然後把值賦給了欄位*/
}
從以上對比,我們可以知道屬性工作的流程。也許您會問知道這些有什麼用呢。嘿嘿,我們知道屬性和欄位的關係之後,可以同過在屬性上寫點東西,達到對欄位的約束作用。
例如:
1. 讓使用者輸入年齡時,使用者可能輸入負值如-17歲或者超過三位數如400歲這些不符合實際的數值,這時候我們就可以通過屬性在使用者輸入時,通過set方法對輸入的值進行約束。
Code部分:
public int Age
{
get { return _age; }
set
{
if (value < 0 || value > 110) /*在對年齡屬性進行賦時可以進行判斷*/
{
value = 0;
}
_age = value;
}
2. 在讓使用者進行填寫性別時,輸入的字元有可能是'公',而我們的目的是想顯示'男'&'女',這時候我們就可以通過屬性在列印時,通過get方法對輸入的值進行約束.
Code部分:
public char Sex
{
get
{
if ( _sex != '男' && _sex != '女' )
{
_sex = '男';
}
return _sex;
}
set { _sex = value; }
}
總結一下:
那麼什麼時候對get方法進行約束,又什麼時候對set方法進行約束呢。答:對屬性進行賦值時對set方法進行約束,比如上面程式碼例項化物件進行傳參 .屬性進行讀取數值時,用get方法進行約束,比如上面用show()方法進行輸出時。
這次就寫到這兒吧,脖子有點疼了。以上都是我學習的時候總結,留備自己再看.如有誤區還請您在評論區指出或者補齊,這裡感謝那些看完這篇blog的人,好吧你們說吧.