【C#】詳解屬性

來源:互聯網
上載者:User

標籤:oid   欄位   use   false   ++   目錄   person   集合   field   

目錄結構:

contents structure [+]
  1. 屬性和欄位的區別
  2. 無參屬性
    1. 自動實作屬性
    2. 對象和集合初始化器
    3. 匿名型別
    4. System.Tuple類型
  3. 有參屬性
  4. 屬性的可訪問性

在這篇文章中,將會詳細介紹屬性(Property)。屬性總的分為兩種,一種是有參屬性(索引器),另一種是無參屬性。

1.屬性和欄位的區別

屬性(Property)和欄位(Field)相比讀者都是見到過的,他們的區別見如下代碼:

    class Person {        public String m_name;//欄位        public Int32 m_age;        public String Name{//屬性            get { return m_name; }            set { m_name = value; }//關鍵字value代表新值        }        public Int32 Age {            get {return m_age;}            set {m_age = value;}        }    }

從上面的定義的Person類可以看出,通常,封裝了欄位訪問的方法就是訪問器(屬性)。

2.無參屬性

無參屬性就是如同上面的Person類中的屬性,無索引器。

2.1 自動實作屬性

C#為無參屬性提供了一種更簡便的文法,稱為自動實現屬性(Automatically Implemented Property 簡稱為API)。
例如:

    class Person {        public String Name{set;get;}        public Int32 Age{get;set;}    }

上面C#會自動為Name和Age屬性聲明欄位,並且也會自動實現Name和Age屬性的主體方法,分別設定和返回欄位中的值。

2.2 對象和集合初始化器

經常要構造一個對象,並設定對象的一些公用屬性(或欄位),C#簡化了這個常見的編程模式。
還是以上面的Person類舉例,在有了Person類中,我們就可以聲明對象和初始化值一步完成(通過無參構造器):

Person person = new Person() { Name="jame",Age=12};

如果屬性實現了IEnumerable或是IEnumerable<T>介面,那麼屬性就會被認為是集合,例如:

    class Classroom {        public List<String> Student { set; get; }    }

然後可以就使用如下的程式碼完成建立Classroom對象並且初始化Student屬性值。

Classroom classroom = new Classroom() { Student = { "green","red","blue"} };
2.3 匿名型別

C#可以利用匿名型別來聲明不可變(immutable)的元群組類型。一旦型別宣告完成後,就不可以更改。
例如:

var o1 = new {Name="jame",Age=12,Sex="男" };//o1.Name = "231";//編譯不通過,因為Name是唯讀屬性。Console.WriteLine(o1.Name);//jameConsole.WriteLine(o1.Age);//12Console.WriteLine(o1.Sex);//男

上面的代碼,C#自動建立一個匿名型別,並且含有Name、Age、Sex的唯讀屬性。

通過上面的代碼可以看出,C#提供匿名型別的文法是:

var o=new {perperty1=expression1,...,perpertyN=expressionN};

C#會推斷每個運算式的類型,並且建立類型的私人欄位,為每個欄位建立公用唯讀屬性,並且建立一個構造器來接受所有這些運算式。

2.4 System.Tuple類型

這裡介紹一下System.Tuple類型,因為System.Tuple類型中的所有屬性都是唯讀。System.Tuple有好幾個泛型版本,區別在於他們的元數(泛型參數的個數)。

//最簡單的泛型Tuple類型[Serializable]public class Tuple<T1>{    private readonly T1 m_Item1;    public T1 Item1 { get { return m_Item1; } }    public Tuple(T1 item1) {        m_Item1 = item1;    }}//最複雜的泛型Tuple泛型型別[Serializable]public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>{         private readonly T1 m_Item1;        private readonly T2 m_Item2;        private readonly T3 m_Item3;        private readonly T4 m_Item4;        private readonly T5 m_Item5;        private readonly T6 m_Item6;        private readonly T7 m_Item7;        private readonly TRest m_Rest;         public T1 Item1 { get { return m_Item1; } }        public T2 Item2 { get { return m_Item2; } }        public T3 Item3 { get { return m_Item3; } }        public T4 Item4 { get { return m_Item4; } }        public T5 Item5 { get { return m_Item5; } }        public T6 Item6 { get { return m_Item6; } }        public T7 Item7 { get { return m_Item7; } }        public TRest Rest { get { return m_Rest; } }         public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) {            m_Item1 = item1;            m_Item2 = item2;            m_Item3 = item3;            m_Item4 = item4;            m_Item5 = item5;            m_Item6 = item6;            m_Item7 = item7;            m_Rest = rest;        }}

Tuple類從System.Object派生,並且實現了IStructuralEquatable, IStructuralComparable介面,它們的是可比較的。
栗子:

static void Main(string[] args){    Tuple<Int32, Int32> vals = MinMax(12,21);    Console.WriteLine(vals.Item1);//12    Console.WriteLine(vals.Item2);//21    Console.ReadLine();}static Tuple<Int32, Int32> MinMax(Int32 a, Int32 b) {    return new Tuple<int, int>(Math.Min(a,b),Math.Max(a,b));}
3.有參屬性

我們將屬性的get訪問器是否能接受參數,分為無參屬性和有參數屬性(索引器)。

CLR本身是不區分有參屬性和無參屬性的。對CLR來說,每個屬性只是類型定義的一對方法和中繼資料。不同的程式設計語言使用使用了不同的文法來建立有參屬性,C#使用this[...]作為表達器索引的文法,因此C#只支援在對象的執行個體上定義索引器。
例如:

class BitArray {    private Byte[] m_byteArray;    private Int32 m_numBits;    public BitArray(Int32 numBits) {        //驗證實參        if (numBits <= 0)            throw new ArgumentException("numBits must be > 0");        //儲存位的個數        m_numBits = numBits;        //為位分配位元組        m_byteArray=new Byte[(numBits+7)/8];//之所以要加7,因為即使位元小於8,也應該有一個位元組。    }    //下面是索引器(有參屬性)    public Boolean this[Int32 bitPos] {        get {            if (bitPos < 0 || bitPos >= m_numBits) {                throw new ArgumentException("bitPos");            }            return (m_byteArray[bitPos/8]&(1<<(bitPos%8)))!=0;//判斷下標(bitPos%8)位的值是否不是0        }        set {            if (bitPos < 0 || bitPos >= m_numBits)            {                throw new ArgumentException("bitPos");            }            if (value)            {                //將指定索引處的位設定為true                m_byteArray[bitPos / 8] = (Byte)(m_byteArray[bitPos / 8] | (1 << (bitPos % 8)));//將下標(bitPos%8)位的值設定為1            }            else {                //將指定索引處的位設定為false                m_byteArray[bitPos / 8] = (Byte)(m_byteArray[bitPos / 8] & ~(1 << (bitPos % 8)));//將下標(bitPos%8)的位的值設定0            }        }    }}

然後就可以像如下這樣來使用BitArray的索引器了。

BitArray ba = new BitArray(14);//調用set訪問器,將所有偶數位都設定為truefor (Int32 x = 0; x < 14; x++) {    ba[x]=(x%2==0);}//調用get訪問器,顯示所有位的狀態。for (Int32 x = 0; x < 14; x++) {    Console.WriteLine("Bit "+x+" is "+(ba[x]?"On":"Off"));}
4.屬性的可訪問性

有時希望為get訪問器方法提供一個可訪問性,為set訪問器方法指定另一種可訪問器。
例如:

public class SomeType{    private String m_name;    public String Name{        get{return m_name;}//預設        protected set{m_name=value;}//指定為protected    }}

 

【C#】詳解屬性

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.