程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#無參屬性

C#無參屬性

編輯:C#入門知識

 

大家來討論下C#無參屬性這個東西到底有沒有存在的必要?

永遠不要公開類型的字段,面向對象設計和編程的重要原則之一就是 數據封裝。如果公開類型的字段,會很容易的寫出不恰當使用字段的代碼。這裡可以把字段聲明為private,然後聲明訪問器方法。

    class test

    {

      

       private  string Name;

       public void SetName(string value)

       {

           Name = value;

       }

       public string GetName()

       {

           return Name;

       }

     

    }

復制代碼

實現只讀或只寫就是這麼簡單,不實現一個索引器方法就行了。還可以將Setname方法標記為protected,就可以只允許派生類修改了。聰明的你也發現上面這個做法的缺點了吧,首先得去實現額外的方法,所以會產生更多的代碼,其次,如果調用的時候必須調用方法,不能直接引用一個字段名。還好C#給我們提供了一個稱為屬性(property)的機制,它緩解了第一個缺點造成的影響,也消除了第二個缺點。

   class test

    {

      

       private  string name;

       public string Name {

           get { return name; }

           set { if ("狗剩" == value) { Console.WriteLine("系統崩潰,拋出異常"); return; } name = value; }

       }

     

    }

復制代碼

屬性可以用任意的可訪問修飾符來標記。不能定義名稱相同的屬性。

如果只是為了封裝一個支持字段而創建屬性,C#還提供一一種更簡單的語法,稱為自動實現的屬性(Automatically Implemented Property,簡稱AIP)。like this

   class test

    {

       public int Age

       {

           get;

           set;

       }

    }

復制代碼

如果聲明一個屬性而不提供get/set實現,C#會自動為你聲明一個私有字段。原始代碼是這樣的:

public int Age

{

    [CompilerGenerated]

    get

    {

        int num;

        num = this.<Age>k__BackingField;

    Label_0009:

        return num;

    }

    [CompilerGenerated]

    set

    {

        this.<Age>k__BackingField = value;

        return;

    }

}

 

復制代碼

和直接聲明一個public 的Age字段相比,自動實現的屬性的優勢在哪?兩者存在一處重要的區別:使用自動實現的屬性(AIP)意味著已經創建一個屬性,訪問該屬性的時候會調用get/set方法。如果有一天你決定自己實現這個AIP的get/set,而不接受編譯器默認的實現,那麼訪問這個屬性的任何代碼都不必重新編譯。如果是一個public的Age字段,如果你把它更改為屬性,那麼訪問這個字段的所有代碼就都需要重新編譯了。

凡事都有好有壞,那麼AIP有哪些不討人喜歡的地方呢:

1.如果使用字段聲明的語法,可以包含初始化的部分,如果使用AIP就不行了,必須在咩個構造器中顯示的初始化每個AIP。

2.AIP支持的字段名是由編譯器決定的,而且每次重新編譯,這個字段名可能會發生更改,這樣一來,只要含有一個AIP就不能對類型的實例進行反序列化了。在任何想要序列化或反序列化的類型中,都不要使用AIP功能。

3.不能在AIP的get/set添加斷點,所以不好檢測程序在什麼時候獲取或設置這個屬性。咱手動實現的就可以設置斷點,不信你試試。

AIP功能是作用於整個屬性的:要麼都用,要麼都不用,這意味這,如果顯式的實現get那麼set也要顯式實現,反之亦然。

 

屬性看起來與字段相似,但本質上是方法。屬性與字段的區別如下:

1.屬性可以是只讀或只寫的(get/set訪問器方法),字段卻總是可讀可寫的。

2.屬性方法可能拋出異常,字段訪問不會拋出。

3.屬性不能作為out或ref參數傳遞給方法,字段可以。

class Program

    {

       public int Age

       {

           get {return 3 ;}

           set{}

       }

       int age;

        static void Main()

        {

            var t = new { name="XiaoBai",age=22 };

            test tt = new test();

            //tt.Name = "狗剩";

            Program p = new Program();

            some(out p.age);

            some(out p.Age);//屬性,索引器或動態成員不得作為out或ref參數傳遞

          Console.ReadKey();

        }

        static void some(out int age)

        {

            age = 10;

        }

    }

www.2cto.com

4.屬性方法可能花費較長時間執行,字段的訪問都是立即完成。

5.屬性方法可能需要額外的內存,或者返回一個不正確的引用,指向不屬於對象狀態一部分的某個東西,這樣一來,對返回對象的修改就作用不到原始對象身上了,相反查詢字段返回的總是正確的引用,它指向的東西保證是原始對象狀態的一部分。使用會返回一個拷貝的屬性時,非常容易引起混淆。

如果仔細研究下屬性和字段的差別,你會發現只有在極個別的情況下屬性才真正有用。屬性唯一的好處就是提供了簡化的語法,和調用普通方法(非屬性中的方法)相比,屬性不僅不會提升代碼的性能,還會妨礙對代碼的理解。

屬性訪問器的可訪問性:

我們有時希望為get訪問器指定一種可訪問性,為set訪問器指定另一種訪問器:

    class test

    {

        public int Age

        {

            get { return age; }

            protected set { if (value < 0) Console.WriteLine("年齡錯誤!"); else { age = value; } }

        }

        int age;

    }

復制代碼

如上所述,Age屬性本身聲明為public,意味這get訪問器方法是公共的,可由所有代碼訪問,但是,注意set訪問器方法被聲明為protected,只能從test的內部定義的代碼中調用,或者從test的派生類的代碼中調用。

定義一個屬性時,如果兩個訪問其方法需要具有不同的可訪問性,C#語法要求必須為屬性本身指定限制最不大的那一種可訪問性,然後在兩個訪問其中,只能選擇一個來應用限制較大的那一種可訪問性。在前面的例子中,屬性本身為public,set訪問器為protected(限制比public大)。

   class test

    {

        private int Age

        {

            get { return age; }

            protected set { if (value < 0) Console.WriteLine("年齡錯誤!"); else { age = value; } }//這裡就通不過編譯

        }

        int age;

    } 

  摘自 小小白白

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