深入分析結構體——結構體里有屬性必須new才能使用?


游哥今天遇到了一個關於結構體的神現象。
簡單點來說就是:
一個結構體,里面沒有屬性,可以不new就使用。但在結構體里面寫了個屬性就必須要new才能使用,這是為什么呢?

直接上代碼:

struct Dog    //狗的結構體
{
    public int age;
}
struct Cat   //貓的結構體
{
    public int Age { get; set; }
}
class Program
{
    public static void Main()
    {
        //情況A
        Dog dog1;
        dog1.age = 3;                 //片段1
        Console.WriteLine(dog1.age);  //不出錯
        Cat cat1;
        cat1.Age = 3;                 //編譯錯誤
        Console.WriteLine(cat1.Age);  //片段2

        //情況B
        Dog dog2 = new Dog();
        dog2.age = 3;                 //片段3
        Console.WriteLine(dog2.age);  //不出錯
        Cat cat2 = new Cat();
        cat2.Age = 3;                 //片段4
        Console.WriteLine(cat2.Age);  //不出錯
    }
}

 

片斷4不報錯,而片斷2則報錯。
這里面涉及很多技術細節,你能知道這是為什么嗎?

 


游哥來解答:
1.結構體里只有字段,沒有屬性。狗類分析:
片斷1,不出錯。眾所周知,結構體可以不new就使用。
片斷3,不出錯。不new不出錯,new了就更不出錯了。

2.結構體可以new,也可以不new。new與不new的區別是,new為會每一個成員字段賦一個默認初值(還記得default關鍵字嗎),而不new則不會這么做。
3.任何一個屬性,編譯器都會自動生成一個與之對應的字段來保存數據,比如這里的Age屬性,就會產生出一個_age來為其保存數據。(它可能不叫_age,這不是重點,總之你看不到這個字段,但它確實存在。)
4.了解一下,什么叫數據結構和算法吧。其實有點扯遠了,簡單來說,可以這么理解,字段就是數據結構,而方法和屬性訪問器就是算法了。(字段保存數據,而方法和屬性訪問器對這些數據進行加工計算)。
5.為什么要提出數據結構和算法,我要說的重點是:要調用結構體的算法(各部門請注意,我要來計算了),必須先讓所有的數據就就緒(那些字段都賦了初值了嗎)。意思就是說,你要調用結構體的任何一個方法或屬性訪問器之前,必須要給所有的字段賦初始。編譯器不會去關心你的算法涉及了哪些字段(編譯器不檢查你的方法體)。甚至是你的算法沒有涉及任何字段的訪問,編譯器依然要求你將所有的字段都賦上初值才能使用。

6.結構里有屬性。貓類分析:
片斷2,編譯錯誤。那個隱藏的_age沒有賦初值,而你寫cat1.Age=3,是調用了Age的set訪問器,set訪問器是一個算法,你要使用這個算法,必須先將所有字段賦初始,而你的_age沒有賦初值,所以就編譯錯誤了。
片斷4,不會出錯。你在new Cat()時,對_age進行了賦初始操作,所以后面就不出錯了。

 

 

一點淺見 歡迎批評指正

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM