程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> CLR筆記:9.Property

CLR筆記:9.Property

編輯:關於.NET

屬性分兩種,無參屬性,有參屬性,後者又叫索引器(indexer)——VB.NET中相應為默認屬性。

1.無參屬性

CLR支持靜態屬性,實例屬性,抽象屬性,虛擬屬性,但不能被重載。

屬性在MSIL中生成以下內容:

get_XX方法,當在屬性中定義了get的時候——XX為屬性名

set_XX方法,當在屬性中定義了set的時候——XX為屬性名

一個位於原數據中的屬性定義。

屬性不能作為out/ref傳遞給方法,字段則可以。

如果屬性中執行語句過多,要花很多時間,這時候優先選用方法。例如線程同步和Remoting。

多次訪問屬性,每次返回的值可能不同;而字段的值每次返回都不會改變。例如System.DateTime屬性 ——MS以後會將其改為方法。

2.有參屬性

定義,有參屬性的get方法可以接受1個或者更多參數,set方法可以接受2個或者更多參數

——對比,無參屬性get方法無參數,set方法有1個參數。

C#索引器語法,是對[ ]這個運算符的重載,示例如下:

    public class FailSoftArray

    {

        int[] a;

        public int length;


        public FailSoftArray(int length)

        {

            a = new int[length];

            this.length = length;

        }


        public int this[int index]

        {

            get 

            {

                if (index >= 0 & index < length)

                {

                    return a[index];

                }

                else

                    throw new ArgumentOutOfRangeException();

            }


            set

            {

                if (index >= 0 & index < length)

                {

                    a[index] = value;

                }

                else

                    throw new ArgumentOutOfRangeException();

            }

        }

    }


    public class TestIndex

    {

        public TestIndex()

        {

            FailSoftArray fs = new FailSoftArray(5);


            for (int i = 0; i < 5; i++)

            {

                fs[i] = i * 10;

            }

        }

    }

索引器是可以重載的,不能在this[]的類型上重載,只能在參數上重載——無參屬性不可以重載:

        public int this[int index]

        {

            set { }

        }


        public int this[double index]

        {

            set { }

        }

以下索引器重載是不對的,盡管改變了Item,在MSIL中是有不同方法名的兩套方法,卻具有相同的參 數集;但是C#不是按名稱引用索引器,而是按參數集。

        [IndexerName("Jeff")]

        public String this[bool b]

        {

            set { }

        }


        [IndexerName("Jax.Bao")]

        public Int32 this[bool b]

        {

            set { }

        }

CLR不區分無參屬性和有參屬性,都是生成一對方法和一塊元數據:

get_Item方法,當在屬性中定義了get的時候

set_Item方法,當在屬性中定義了set的時候

一個位於原數據中的屬性定義。在MSIL中,有專門用於有參屬性的元數據定義表。

對於索引器,使用get_Item和set_Item這兩個默認名稱。同時,通過反射查看類型是否有Item屬性, 來判斷該類型是否提供了索引器(Generic.List)。

但是,C#編程中不會看到Item這一默認屬性,在與其它語言交互時,可能需要把Item改為其他的名稱 ,方法如下:

    using System.Runtime.CompilerServices;
    public sealed class BitArray

    {

        [IndexerName("Bit")]

        public bool this[int bitPos]

        {

            set { }

        }

    }

於是,MSIL生成get_Bit和set_Bit方法。NET中的String.String類型就是Chars而不是Item。

索引器語法this[..],是C#團隊選擇的表示方式,意味著C#只允許在對象的實例上定義索引器。

CLR支持靜態有參屬性,但是C#沒有提供相關語法

補充:VB.NET"默認屬性"語法

將C#的索引器示例改造成VB.NET的:將屬性聲明為Default,並加上參數,只是這裡的this不再是關鍵 字,而是一個自定義的屬性

Public Class FailSoftArrayClass FailSoftArray
    Public length As Integer

    Private a(length) As Integer



    Public Sub New()Sub New(ByVal length As Integer)

        Me.length = length

    End Sub
    Default Public Property Name()Property this(ByVal index As Integer)

        Get

            If (index >= 0 & index < length) Then

                Return a(index)

            Else

                Throw New ArgumentOutOfRangeException()

            End If

        End Get

        Set(ByVal value)

            If (index >= 0 & index < length) Then

                a(index) = value

            Else

                Throw New ArgumentOutOfRangeException()

            End If

        End Set

    End Property

End Class
Public Class TestIndexClass TestIndex

    Public Sub New()Sub New()

        Dim fs As FailSoftArray = New FailSoftArray(5)


        Dim i As Integer

        For i = 1 To 5

            fs(i) = i * 10

        Next

    End Sub

End Class

3.性能

內聯:就是方法下包括全部代碼,不需要將部分代碼放到額外的調用函數中——消除了運行時與調用 相關的開銷,代價是編譯後方法的代碼很龐大。

內聯屬性方法,因為其通常包括極少代碼,所以編譯後代碼量更小,執行更快。

由於JIT調試時期不會內聯屬性方法,所以屬性訪問器在Release版本性能要快於Debug版本——字段在 兩個版本中執行得同樣快。

4.屬性訪問器的可訪問性

可以get是public的;而set是protected的

get/set的可訪問性是在屬性名前聲明的

        public String Name  //這裡的public決定了get/set默認的可訪問性

        {

            get { return null; }

            protected set { }   //這裡提升了set的可訪問性

        }

5.雖然屬性實際上就是方法,但是不允許泛型屬性。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved