[{"data":1,"prerenderedAt":1208},["ShallowReactive",2],{"note-\u002Fnotes\u002Fsync\u002Fcsharp-02":3},{"id":4,"title":5,"body":6,"category":1194,"date":1195,"description":1196,"draft":1197,"extension":1198,"meta":1199,"navigation":66,"path":1200,"seo":1201,"sourcePath":1202,"stem":1203,"tags":1204,"__hash__":1207},"notes\u002Fnotes\u002Fsync\u002Fcsharp-易混淆概念-易混淆概念02.md","易混淆概念02",{"type":7,"value":8,"toc":1181},"minimark",[9,13,522,526,550,554,578,580,600,602,612,652,655,663,665,668,677,693,695,700,783,785,790,798,853,855,860,887,890,894,902,905,909,912,915,952,956,962,1006,1009,1013,1033,1035,1039,1042,1097,1099,1103,1106,1111,1122,1130,1133,1137,1140,1149,1157,1161,1175,1177],[10,11,12],"h2",{"id":12},"物件的繼承",[14,15,20],"pre",{"className":16,"code":17,"language":18,"meta":19,"style":19},"language-csharp! shiki shiki-themes github-light github-dark","\u002F\u002F WorkItem implicitly inherits from the Object class.\npublic class WorkItem\n{\n    \u002F\u002F Static field currentID stores the job ID of the last WorkItem that\n    \u002F\u002F has been created.\n    private static int currentID;\n\n    \u002F\u002FProperties.\n    protected int ID { get; set; }\n    protected string Title { get; set; }\n    protected string Description { get; set; }\n    protected TimeSpan jobLength { get; set; }\n\n    \u002F\u002F Default constructor. If a derived class does not invoke a base-\n    \u002F\u002F class constructor explicitly, the default constructor is called\n    \u002F\u002F implicitly.\n    public WorkItem()\n    {\n        ID = 0;\n        Title = \"Default title\";\n        Description = \"Default description.\";\n        jobLength = new TimeSpan();\n    }\n\n    \u002F\u002F Instance constructor that has three parameters.\n    public WorkItem(string title, string desc, TimeSpan joblen)\n    {\n        ID = GetNextID();\n        Title = title;\n        Description = desc;\n        jobLength = joblen;\n    }\n\n    \u002F\u002F Static constructor to initialize the static member, currentID. This\n    \u002F\u002F constructor is called one time, automatically, before any instance\n    \u002F\u002F of WorkItem or ChangeRequest is created, or currentID is referenced.\n    static WorkItem() => currentID = 0;\n\n    \u002F\u002F currentID is a static field. It is incremented each time a new\n    \u002F\u002F instance of WorkItem is created.\n    protected int GetNextID() => ++currentID;\n\n    \u002F\u002F Method Update enables you to update the title and job length of an\n    \u002F\u002F existing WorkItem object.\n    public void Update(string title, TimeSpan joblen)\n    {\n        this.Title = title;\n        this.jobLength = joblen;\n    }\n\n    \u002F\u002F Virtual method override of the ToString method that is inherited\n    \u002F\u002F from System.Object.\n    public override string ToString() =>\n        $\"{this.ID} - {this.Title}\";\n}\n\n\u002F\u002F ChangeRequest derives from WorkItem and adds a property (originalItemID)\n\u002F\u002F and two constructors.\npublic class ChangeRequest : WorkItem\n{\n    protected int originalItemID { get; set; }\n\n    \u002F\u002F Constructors. Because neither constructor calls a base-class\n    \u002F\u002F constructor explicitly, the default constructor in the base class\n    \u002F\u002F is called implicitly. The base class must contain a default\n    \u002F\u002F constructor.\n\n    \u002F\u002F Default constructor for the derived class.\n    public ChangeRequest() { }\n\n    \u002F\u002F Instance constructor that has four parameters.\n    public ChangeRequest(string title, string desc, TimeSpan jobLen,\n                         int originalID)\n    {\n        \u002F\u002F The following properties and the GetNexID method are inherited\n        \u002F\u002F from WorkItem.\n        this.ID = GetNextID();\n        this.Title = title;\n        this.Description = desc;\n        this.jobLength = jobLen;\n\n        \u002F\u002F Property originalItemID is a member of ChangeRequest, but not\n        \u002F\u002F of WorkItem.\n        this.originalItemID = originalID;\n    }\n}\n","csharp!","",[21,22,23,31,37,43,49,55,61,68,74,80,86,92,98,103,109,115,121,127,133,139,145,151,157,163,168,174,180,185,191,197,203,209,214,219,225,231,237,243,248,254,260,266,271,277,283,289,294,300,306,311,316,322,328,334,340,346,351,357,363,369,374,380,385,391,397,403,409,414,420,426,431,437,443,449,454,460,466,472,477,483,489,494,500,506,512,517],"code",{"__ignoreMap":19},[24,25,28],"span",{"class":26,"line":27},"line",1,[24,29,30],{},"\u002F\u002F WorkItem implicitly inherits from the Object class.\n",[24,32,34],{"class":26,"line":33},2,[24,35,36],{},"public class WorkItem\n",[24,38,40],{"class":26,"line":39},3,[24,41,42],{},"{\n",[24,44,46],{"class":26,"line":45},4,[24,47,48],{},"    \u002F\u002F Static field currentID stores the job ID of the last WorkItem that\n",[24,50,52],{"class":26,"line":51},5,[24,53,54],{},"    \u002F\u002F has been created.\n",[24,56,58],{"class":26,"line":57},6,[24,59,60],{},"    private static int currentID;\n",[24,62,64],{"class":26,"line":63},7,[24,65,67],{"emptyLinePlaceholder":66},true,"\n",[24,69,71],{"class":26,"line":70},8,[24,72,73],{},"    \u002F\u002FProperties.\n",[24,75,77],{"class":26,"line":76},9,[24,78,79],{},"    protected int ID { get; set; }\n",[24,81,83],{"class":26,"line":82},10,[24,84,85],{},"    protected string Title { get; set; }\n",[24,87,89],{"class":26,"line":88},11,[24,90,91],{},"    protected string Description { get; set; }\n",[24,93,95],{"class":26,"line":94},12,[24,96,97],{},"    protected TimeSpan jobLength { get; set; }\n",[24,99,101],{"class":26,"line":100},13,[24,102,67],{"emptyLinePlaceholder":66},[24,104,106],{"class":26,"line":105},14,[24,107,108],{},"    \u002F\u002F Default constructor. If a derived class does not invoke a base-\n",[24,110,112],{"class":26,"line":111},15,[24,113,114],{},"    \u002F\u002F class constructor explicitly, the default constructor is called\n",[24,116,118],{"class":26,"line":117},16,[24,119,120],{},"    \u002F\u002F implicitly.\n",[24,122,124],{"class":26,"line":123},17,[24,125,126],{},"    public WorkItem()\n",[24,128,130],{"class":26,"line":129},18,[24,131,132],{},"    {\n",[24,134,136],{"class":26,"line":135},19,[24,137,138],{},"        ID = 0;\n",[24,140,142],{"class":26,"line":141},20,[24,143,144],{},"        Title = \"Default title\";\n",[24,146,148],{"class":26,"line":147},21,[24,149,150],{},"        Description = \"Default description.\";\n",[24,152,154],{"class":26,"line":153},22,[24,155,156],{},"        jobLength = new TimeSpan();\n",[24,158,160],{"class":26,"line":159},23,[24,161,162],{},"    }\n",[24,164,166],{"class":26,"line":165},24,[24,167,67],{"emptyLinePlaceholder":66},[24,169,171],{"class":26,"line":170},25,[24,172,173],{},"    \u002F\u002F Instance constructor that has three parameters.\n",[24,175,177],{"class":26,"line":176},26,[24,178,179],{},"    public WorkItem(string title, string desc, TimeSpan joblen)\n",[24,181,183],{"class":26,"line":182},27,[24,184,132],{},[24,186,188],{"class":26,"line":187},28,[24,189,190],{},"        ID = GetNextID();\n",[24,192,194],{"class":26,"line":193},29,[24,195,196],{},"        Title = title;\n",[24,198,200],{"class":26,"line":199},30,[24,201,202],{},"        Description = desc;\n",[24,204,206],{"class":26,"line":205},31,[24,207,208],{},"        jobLength = joblen;\n",[24,210,212],{"class":26,"line":211},32,[24,213,162],{},[24,215,217],{"class":26,"line":216},33,[24,218,67],{"emptyLinePlaceholder":66},[24,220,222],{"class":26,"line":221},34,[24,223,224],{},"    \u002F\u002F Static constructor to initialize the static member, currentID. This\n",[24,226,228],{"class":26,"line":227},35,[24,229,230],{},"    \u002F\u002F constructor is called one time, automatically, before any instance\n",[24,232,234],{"class":26,"line":233},36,[24,235,236],{},"    \u002F\u002F of WorkItem or ChangeRequest is created, or currentID is referenced.\n",[24,238,240],{"class":26,"line":239},37,[24,241,242],{},"    static WorkItem() => currentID = 0;\n",[24,244,246],{"class":26,"line":245},38,[24,247,67],{"emptyLinePlaceholder":66},[24,249,251],{"class":26,"line":250},39,[24,252,253],{},"    \u002F\u002F currentID is a static field. It is incremented each time a new\n",[24,255,257],{"class":26,"line":256},40,[24,258,259],{},"    \u002F\u002F instance of WorkItem is created.\n",[24,261,263],{"class":26,"line":262},41,[24,264,265],{},"    protected int GetNextID() => ++currentID;\n",[24,267,269],{"class":26,"line":268},42,[24,270,67],{"emptyLinePlaceholder":66},[24,272,274],{"class":26,"line":273},43,[24,275,276],{},"    \u002F\u002F Method Update enables you to update the title and job length of an\n",[24,278,280],{"class":26,"line":279},44,[24,281,282],{},"    \u002F\u002F existing WorkItem object.\n",[24,284,286],{"class":26,"line":285},45,[24,287,288],{},"    public void Update(string title, TimeSpan joblen)\n",[24,290,292],{"class":26,"line":291},46,[24,293,132],{},[24,295,297],{"class":26,"line":296},47,[24,298,299],{},"        this.Title = title;\n",[24,301,303],{"class":26,"line":302},48,[24,304,305],{},"        this.jobLength = joblen;\n",[24,307,309],{"class":26,"line":308},49,[24,310,162],{},[24,312,314],{"class":26,"line":313},50,[24,315,67],{"emptyLinePlaceholder":66},[24,317,319],{"class":26,"line":318},51,[24,320,321],{},"    \u002F\u002F Virtual method override of the ToString method that is inherited\n",[24,323,325],{"class":26,"line":324},52,[24,326,327],{},"    \u002F\u002F from System.Object.\n",[24,329,331],{"class":26,"line":330},53,[24,332,333],{},"    public override string ToString() =>\n",[24,335,337],{"class":26,"line":336},54,[24,338,339],{},"        $\"{this.ID} - {this.Title}\";\n",[24,341,343],{"class":26,"line":342},55,[24,344,345],{},"}\n",[24,347,349],{"class":26,"line":348},56,[24,350,67],{"emptyLinePlaceholder":66},[24,352,354],{"class":26,"line":353},57,[24,355,356],{},"\u002F\u002F ChangeRequest derives from WorkItem and adds a property (originalItemID)\n",[24,358,360],{"class":26,"line":359},58,[24,361,362],{},"\u002F\u002F and two constructors.\n",[24,364,366],{"class":26,"line":365},59,[24,367,368],{},"public class ChangeRequest : WorkItem\n",[24,370,372],{"class":26,"line":371},60,[24,373,42],{},[24,375,377],{"class":26,"line":376},61,[24,378,379],{},"    protected int originalItemID { get; set; }\n",[24,381,383],{"class":26,"line":382},62,[24,384,67],{"emptyLinePlaceholder":66},[24,386,388],{"class":26,"line":387},63,[24,389,390],{},"    \u002F\u002F Constructors. Because neither constructor calls a base-class\n",[24,392,394],{"class":26,"line":393},64,[24,395,396],{},"    \u002F\u002F constructor explicitly, the default constructor in the base class\n",[24,398,400],{"class":26,"line":399},65,[24,401,402],{},"    \u002F\u002F is called implicitly. The base class must contain a default\n",[24,404,406],{"class":26,"line":405},66,[24,407,408],{},"    \u002F\u002F constructor.\n",[24,410,412],{"class":26,"line":411},67,[24,413,67],{"emptyLinePlaceholder":66},[24,415,417],{"class":26,"line":416},68,[24,418,419],{},"    \u002F\u002F Default constructor for the derived class.\n",[24,421,423],{"class":26,"line":422},69,[24,424,425],{},"    public ChangeRequest() { }\n",[24,427,429],{"class":26,"line":428},70,[24,430,67],{"emptyLinePlaceholder":66},[24,432,434],{"class":26,"line":433},71,[24,435,436],{},"    \u002F\u002F Instance constructor that has four parameters.\n",[24,438,440],{"class":26,"line":439},72,[24,441,442],{},"    public ChangeRequest(string title, string desc, TimeSpan jobLen,\n",[24,444,446],{"class":26,"line":445},73,[24,447,448],{},"                         int originalID)\n",[24,450,452],{"class":26,"line":451},74,[24,453,132],{},[24,455,457],{"class":26,"line":456},75,[24,458,459],{},"        \u002F\u002F The following properties and the GetNexID method are inherited\n",[24,461,463],{"class":26,"line":462},76,[24,464,465],{},"        \u002F\u002F from WorkItem.\n",[24,467,469],{"class":26,"line":468},77,[24,470,471],{},"        this.ID = GetNextID();\n",[24,473,475],{"class":26,"line":474},78,[24,476,299],{},[24,478,480],{"class":26,"line":479},79,[24,481,482],{},"        this.Description = desc;\n",[24,484,486],{"class":26,"line":485},80,[24,487,488],{},"        this.jobLength = jobLen;\n",[24,490,492],{"class":26,"line":491},81,[24,493,67],{"emptyLinePlaceholder":66},[24,495,497],{"class":26,"line":496},82,[24,498,499],{},"        \u002F\u002F Property originalItemID is a member of ChangeRequest, but not\n",[24,501,503],{"class":26,"line":502},83,[24,504,505],{},"        \u002F\u002F of WorkItem.\n",[24,507,509],{"class":26,"line":508},84,[24,510,511],{},"        this.originalItemID = originalID;\n",[24,513,515],{"class":26,"line":514},85,[24,516,162],{},[24,518,520],{"class":26,"line":519},86,[24,521,345],{},[523,524,525],"h3",{"id":525},"絕對事實",[527,528,529],"ol",{},[530,531,532,533,536,537,540,541],"li",{},"一個物件的",[21,534,535],{},"建構子","跟",[21,538,539],{},"物件本身","需要同名\n",[542,543,544,547],"ul",{},[530,545,546],{},"兒子的類別叫 ChangeRequest，他的建構子就只能叫 public ChangeRequest()。",[530,548,549],{},"老爸的 public WorkItem() 名字天生不合，所以絕對無法被繼承。",[551,552,553],"p",{},"+++++++++++++",[527,555,556],{"start":33},[530,557,558,559,562,563,566,567,569,570],{},"繼承的部分是",[21,560,561],{},"屬性","+",[21,564,565],{},"方法","，",[21,568,535],{},"無法被繼承：\n",[542,571,572],{},[530,573,574,575],{},"因為",[21,576,577],{},"建構子跟物件本身需要同名",[551,579,553],{},[527,581,582],{"start":39},[530,583,584,585,536,587,589,590,595],{},"繼承來的",[21,586,561],{},[21,588,565],{},"可以隨意使用、也可以不用\n",[591,592],"img",{"alt":593,"src":594},"image","https:\u002F\u002Fhackmd.io\u002F_uploads\u002FSyFxL_Olzx.png",[542,596,597],{},[530,598,599],{},"兒子(ChangeRequest)擁有這些資產的絕對主導權",[551,601,553],{},[527,603,604],{"start":45},[530,605,606,607],{},"孫子繼承兒子，即使兒子沒說明，孫子也能拿到曾祖父的財產？\n",[542,608,609],{},[530,610,611],{},"在物件導向裡叫做「傳遞性（Transitivity）」",[14,613,617],{"className":614,"code":615,"language":616,"meta":19,"style":19},"language-Plaintext! shiki shiki-themes github-light github-dark","👴 曾祖父 Object  ➔ 留下了 ToString() 技能\n  │\n👨 爺爺 WorkItem  ➔ 繼承了 ToString()，自己又發明了 ID, Title, Update()\n  │\n👦 爸爸 ChangeRequest ➔ 什麼都不寫（肚子裡空空如也）\n  │\n👶 孫子 SuperChangeRequest ➔ 宣布繼承爸爸！\n","Plaintext!",[21,618,619,624,629,634,638,643,647],{"__ignoreMap":19},[24,620,621],{"class":26,"line":27},[24,622,623],{},"👴 曾祖父 Object  ➔ 留下了 ToString() 技能\n",[24,625,626],{"class":26,"line":33},[24,627,628],{},"  │\n",[24,630,631],{"class":26,"line":39},[24,632,633],{},"👨 爺爺 WorkItem  ➔ 繼承了 ToString()，自己又發明了 ID, Title, Update()\n",[24,635,636],{"class":26,"line":45},[24,637,628],{},[24,639,640],{"class":26,"line":51},[24,641,642],{},"👦 爸爸 ChangeRequest ➔ 什麼都不寫（肚子裡空空如也）\n",[24,644,645],{"class":26,"line":57},[24,646,628],{},[24,648,649],{"class":26,"line":63},[24,650,651],{},"👶 孫子 SuperChangeRequest ➔ 宣布繼承爸爸！\n",[551,653,654],{},"這時候，這個孫子（SuperChangeRequest）落地時，他的記憶體大樓會發生神蹟：",[527,656,657,660],{},[530,658,659],{},"他往上看，爸爸雖然是一隻空白的 Class，但爸爸的血脈裡流著爺爺的基因。",[530,661,662],{},"所以，孫子全自動、不需要任何人敘明，直接打包繼承了爺爺的 ID、Title、Update()，甚至曾祖父的 ToString()！",[551,664,553],{},[551,666,667],{},"5.那為什麼建構子的大括號 { } 內部，會出現屬性的名字（ID、Title）？這不就代表建構子內部『有』屬性嗎？",[14,669,671],{"className":16,"code":670,"language":18,"meta":19,"style":19},"Title = title;\n",[21,672,673],{"__ignoreMap":19},[24,674,675],{"class":26,"line":27},[24,676,670],{},[542,678,679,690],{},[530,680,681,682],{},"在記憶體的實體世界裡，這行代碼要拆成左邊與右邊：\n",[542,683,684,687],{},[530,685,686],{},"右邊的 title（參數）：它是外面貨車送來的全新材料（例如字串 \"Default title\"）。它確實暫時活在建構子的肚子（Stack 區域）裡。",[530,688,689],{},"左邊的 Title（屬性）：它是死死固定在 Heap 區大樓外牆上的「實體信箱」。",[530,691,692],{},"建構子這個「郵差」，在執行期間走到大樓外牆前，伸手把貨車上的材料（右邊的 title），塞進大樓原本就有的橘色信箱（左邊的 Title）裡。",[551,694,553],{},[527,696,697],{"start":57},[530,698,699],{},"「定義」與「呼叫」的物理界線",[14,701,703],{"className":16,"code":702,"language":18,"meta":19,"style":19},"public class WorkItem\n{\n    \u002F\u002F ===================================================\n    \u002F\u002F 🧱 【這是定義】真正挖在 Heap 區大樓肉身上的「實體記憶體格子」\n    \u002F\u002F ===================================================\n    protected int ID { get; set; }\n    protected string Title { get; set; }\n\n\n    \u002F\u002F ===================================================\n    \u002F\u002F 🛠️ 【這是動作】一段通電執行的機器碼，肚子裡只有「通電指令」\n    \u002F\u002F ===================================================\n    public WorkItem(string title)\n    {\n        \u002F\u002F 🚨 物理真相：這不叫「內含屬性」，這叫「指令：把 title 的電流導向牆上的 Title 格子」\n        this.Title = title; \n    }\n}\n",[21,704,705,709,713,718,723,727,731,735,739,743,747,752,756,761,765,770,775,779],{"__ignoreMap":19},[24,706,707],{"class":26,"line":27},[24,708,36],{},[24,710,711],{"class":26,"line":33},[24,712,42],{},[24,714,715],{"class":26,"line":39},[24,716,717],{},"    \u002F\u002F ===================================================\n",[24,719,720],{"class":26,"line":45},[24,721,722],{},"    \u002F\u002F 🧱 【這是定義】真正挖在 Heap 區大樓肉身上的「實體記憶體格子」\n",[24,724,725],{"class":26,"line":51},[24,726,717],{},[24,728,729],{"class":26,"line":57},[24,730,79],{},[24,732,733],{"class":26,"line":63},[24,734,85],{},[24,736,737],{"class":26,"line":70},[24,738,67],{"emptyLinePlaceholder":66},[24,740,741],{"class":26,"line":76},[24,742,67],{"emptyLinePlaceholder":66},[24,744,745],{"class":26,"line":82},[24,746,717],{},[24,748,749],{"class":26,"line":88},[24,750,751],{},"    \u002F\u002F 🛠️ 【這是動作】一段通電執行的機器碼，肚子裡只有「通電指令」\n",[24,753,754],{"class":26,"line":94},[24,755,717],{},[24,757,758],{"class":26,"line":100},[24,759,760],{},"    public WorkItem(string title)\n",[24,762,763],{"class":26,"line":105},[24,764,132],{},[24,766,767],{"class":26,"line":111},[24,768,769],{},"        \u002F\u002F 🚨 物理真相：這不叫「內含屬性」，這叫「指令：把 title 的電流導向牆上的 Title 格子」\n",[24,771,772],{"class":26,"line":117},[24,773,774],{},"        this.Title = title; \n",[24,776,777],{"class":26,"line":123},[24,778,162],{},[24,780,781],{"class":26,"line":129},[24,782,345],{},[551,784,553],{},[527,786,787],{"start":63},[530,788,789],{},"為什麼class沒有static標籤也住在heap-static當中?",[542,791,792,795],{},[530,793,794],{},"因為 「類別（Class）本身」不需要標籤，它出生就自帶最頂級的 VIP 通行證！",[530,796,797],{},"class 的本質就是「靜態設計圖」",[14,799,803],{"className":800,"code":801,"language":802,"meta":19,"style":19},"language-plaintext! shiki shiki-themes github-light github-dark","【 🎬 記憶體大連動三幕劇 】\n\n 🟢 第一幕：程式開車通電 (Heap-Static 誕生)\n   [Heap-Static] ──載入 WorkItem 藍圖與 currentID ──➔ 萬事俱備\n                          │\n 🔵 第二幕：執行 new WorkItem() (Stack 點火)\n   [Stack] ───────➔ 壓入建構子工兵框架，手持 \"0\" 與 \"Default title\" 指令\n                          │\n 🟣 第三幕：工兵動工 (Heap-Heap 灌漿)\n   [Heap-Heap] ────➔ 挖出實體房間，由 Stack 電流將值寫入 ID 與 Title 房間\n","plaintext!",[21,804,805,810,814,819,824,829,834,839,843,848],{"__ignoreMap":19},[24,806,807],{"class":26,"line":27},[24,808,809],{},"【 🎬 記憶體大連動三幕劇 】\n",[24,811,812],{"class":26,"line":33},[24,813,67],{"emptyLinePlaceholder":66},[24,815,816],{"class":26,"line":39},[24,817,818],{}," 🟢 第一幕：程式開車通電 (Heap-Static 誕生)\n",[24,820,821],{"class":26,"line":45},[24,822,823],{},"   [Heap-Static] ──載入 WorkItem 藍圖與 currentID ──➔ 萬事俱備\n",[24,825,826],{"class":26,"line":51},[24,827,828],{},"                          │\n",[24,830,831],{"class":26,"line":57},[24,832,833],{}," 🔵 第二幕：執行 new WorkItem() (Stack 點火)\n",[24,835,836],{"class":26,"line":63},[24,837,838],{},"   [Stack] ───────➔ 壓入建構子工兵框架，手持 \"0\" 與 \"Default title\" 指令\n",[24,840,841],{"class":26,"line":70},[24,842,828],{},[24,844,845],{"class":26,"line":76},[24,846,847],{}," 🟣 第三幕：工兵動工 (Heap-Heap 灌漿)\n",[24,849,850],{"class":26,"line":82},[24,851,852],{},"   [Heap-Heap] ────➔ 挖出實體房間，由 Stack 電流將值寫入 ID 與 Title 房間\n",[551,854,553],{},[527,856,857],{"start":70},[530,858,859],{},"那struct是住在stack他也是住在heap-static嗎?",[542,861,862,865],{},[530,863,864],{},"Struct 的「設計圖」住哪裡？➔ 【Heap-Static】",[530,866,867,868],{},"Struct 的「肉身實體」住哪裡？➔ 【看它寄生在誰身上！】\n",[542,869,870,873],{},[530,871,872],{},"class 很高傲，不管被誰呼叫，都一定要在 Heap-Heap 圈地蓋獨立大樓，別人只能拿指針（Pointer）指著它。",[530,874,875,876],{},"struct（值型別）非常卑微，它沒有自己獨立的大樓（沒有物件車頭、沒有指針指著它）。它的物理特性是：「宿主（Container）住哪裡，它就原地寄生在哪裡！」\n",[542,877,878,881,884],{},[530,879,880],{},"宿主是「方法工兵」：你寫在方法肚子裡當區域變數 ➔ 宿主在 【Stack】，它就直接嵌在 Stack 的格子裡。",[530,882,883],{},"宿主是「Class大樓」：你寫在 Class 裡面當成員屬性 ➔ 宿主在 【Heap-Heap】，它就直接變成了大樓牆壁的一部分，死死躺在 Heap-Heap 裡。",[530,885,886],{},"宿主是「Static標籤」：你把它宣告成靜態成員 ➔ 宿主在 【Heap-Static】，它就直接焊在 Heap-Static 的設計圖旁邊。",[551,888,889],{},"=======================",[523,891,893],{"id":892},"總結","總結:",[527,895,896,899],{},[530,897,898],{},"方法與屬性 ➔ 走的是 「基因血脈鏈」，代代相傳，只要沒被 sealed（封印），孫子就可以一路啃老啃到最上層。",[530,900,901],{},"建構子 ➔ 走的是 「每代獨立的剪綵大門」，每個人名字都不同，無法繼承，只能在自己開門時，在幕後拉一條隱密通道（Constructor Chaining）去請老爸的推進器幫忙點火。",[903,904],"hr",{},[10,906,908],{"id":907},"heapstack的無殼理論","heap\u002Fstack的無殼理論",[523,910,911],{"id":911},"值型別的深層真相",[551,913,914],{},"前面關於值型別都是說他是一筆真實的資料保存在stack中，可以更快速的存取，看似比參考型別這種之神資料保存在heap，在stack僅有位址(門牌)更基現代化，但其實不然:",[542,916,917,925,944],{},[530,918,919,920],{},"本質是「沒有指針外殼的純資料」",[542,921,922],{},[530,923,924],{},"它不像 Class 擁有高傲的 VIP 外殼（沒有 Object Header 和 Method Table Pointer）。它全身光溜溜的，就是純粹的二進位資料顆粒（例如 int 是 4 Bytes、TimeSpan 是 8 Bytes）。",[530,926,927,928],{},"因為沒有殼，它絕對無法「獨立」在 Heap-Heap 區開戶",[542,929,930],{},[530,931,932,933],{},"它是一堆沒有腳的樂高積木，它的物理居住地址完全取決於它抱到誰的大腿（宿主）：\n",[542,934,935,938,941],{},[530,936,937],{},"孤身一人（方法內的區域變數） ➔ 只能肉身躺在 Stack 的臨時工作檯上。",[530,939,940],{},"抱到大腿（Class 內部的成員屬性） ➔ 隨著 Class 大樓一起嵌在 Heap-Heap 的實體牆壁裡。",[530,942,943],{},"自帶標籤（加了 static 關鍵字） ➔ 直接焊在 Heap-Static 的設計圖旁邊。",[530,945,946,947],{},"觸發硬體大坑：裝箱（Boxing）的代價",[542,948,949],{},[530,950,951],{},"當你強迫一個無殼的值型別，非要硬生生把它塞給 object 或是介面（Interface）時，系統為了讓它能獨立待在 Heap-Heap，必須在幕後手工幫它打造一個「臨時的塑膠殼」。這個裝箱動作會劇烈消耗 CPU 算力，並在 Heap 區產生記憶體碎片。",[523,953,955],{"id":954},"_1-為什麼class沒有static標籤也住在heap-static當中","1. 為什麼class沒有static標籤也住在heap-static當中?",[542,957,958,960],{},[530,959,794],{},[530,961,797],{},[14,963,964],{"className":800,"code":801,"language":802,"meta":19,"style":19},[21,965,966,970,974,978,982,986,990,994,998,1002],{"__ignoreMap":19},[24,967,968],{"class":26,"line":27},[24,969,809],{},[24,971,972],{"class":26,"line":33},[24,973,67],{"emptyLinePlaceholder":66},[24,975,976],{"class":26,"line":39},[24,977,818],{},[24,979,980],{"class":26,"line":45},[24,981,823],{},[24,983,984],{"class":26,"line":51},[24,985,828],{},[24,987,988],{"class":26,"line":57},[24,989,833],{},[24,991,992],{"class":26,"line":63},[24,993,838],{},[24,995,996],{"class":26,"line":70},[24,997,828],{},[24,999,1000],{"class":26,"line":76},[24,1001,847],{},[24,1003,1004],{"class":26,"line":82},[24,1005,852],{},[551,1007,1008],{},"===================",[523,1010,1012],{"id":1011},"_2-那struct是住在stack他也是住在heap-static嗎","2. 那struct是住在stack他也是住在heap-static嗎?",[542,1014,1015,1017],{},[530,1016,864],{},[530,1018,867,1019],{},[542,1020,1021,1023],{},[530,1022,872],{},[530,1024,875,1025],{},[542,1026,1027,1029,1031],{},[530,1028,880],{},[530,1030,883],{},[530,1032,886],{},[551,1034,1008],{},[523,1036,1038],{"id":1037},"_3-c-的宇宙大一統萬物皆自-object-出","3. C# 的宇宙大一統：萬物皆自 object 出",[551,1040,1041],{},"微軟架構師立下了一條鐵律：全宇宙不論是多高傲的 class，還是多卑微的 struct（如 int、bool），它們往上追溯無數代，共同的始祖只有一個，叫做 System.Object（關鍵字小寫的 object）。",[14,1043,1045],{"className":614,"code":1044,"language":616,"meta":19,"style":19},"👑 object (System.Object) ➔ 它是全宇宙最頂層的 Class！\n                                 │\n         ┌───────────────────────┴───────────────────────┐\n         ▼                                               ▼\n【參考型別流派 (Reference Types)】             【值型別流派 (Value Types)】\n   • 所有自訂的普通 class                       • 核心中樞：System.ValueType (也是一隻 Class)\n   • 所有的 string、陣列、介面                             │\n                                                         ▼\n                                               • 所有的 struct (如 Point)\n                                               • 所有的內建基本型別 (int, bool, TimeSpan)\n",[21,1046,1047,1052,1057,1062,1067,1072,1077,1082,1087,1092],{"__ignoreMap":19},[24,1048,1049],{"class":26,"line":27},[24,1050,1051],{},"👑 object (System.Object) ➔ 它是全宇宙最頂層的 Class！\n",[24,1053,1054],{"class":26,"line":33},[24,1055,1056],{},"                                 │\n",[24,1058,1059],{"class":26,"line":39},[24,1060,1061],{},"         ┌───────────────────────┴───────────────────────┐\n",[24,1063,1064],{"class":26,"line":45},[24,1065,1066],{},"         ▼                                               ▼\n",[24,1068,1069],{"class":26,"line":51},[24,1070,1071],{},"【參考型別流派 (Reference Types)】             【值型別流派 (Value Types)】\n",[24,1073,1074],{"class":26,"line":57},[24,1075,1076],{},"   • 所有自訂的普通 class                       • 核心中樞：System.ValueType (也是一隻 Class)\n",[24,1078,1079],{"class":26,"line":63},[24,1080,1081],{},"   • 所有的 string、陣列、介面                             │\n",[24,1083,1084],{"class":26,"line":70},[24,1085,1086],{},"                                                         ▼\n",[24,1088,1089],{"class":26,"line":76},[24,1090,1091],{},"                                               • 所有的 struct (如 Point)\n",[24,1093,1094],{"class":26,"line":82},[24,1095,1096],{},"                                               • 所有的內建基本型別 (int, bool, TimeSpan)\n",[551,1098,1008],{},[523,1100,1102],{"id":1101},"_4-無殼的-struct-怎麼去繼承身為-class-的-object","4. 無殼的 struct 怎麼去繼承身為 Class 的 object？",[551,1104,1105],{},"這是 C# 語言設計史上最偉大的「雙面人設計」，用來解決「名義上的血緣」與「記憶體長相」的物理衝突：",[1107,1108,1110],"h4",{"id":1109},"a-在日常生活裡未裝箱狀態","A. 在日常生活裡（未裝箱狀態）",[551,1112,1113,1114,1117,1118,1121],{},"當宣告 ",[21,1115,1116],{},"int age = 25;"," 或者",[21,1119,1120],{},"TimeSpan time = new TimeSpan();","時：",[542,1123,1124,1127],{},[530,1125,1126],{},"追求極致的快取效率與零 GC 壓力 -> C# 會完全隱瞞它繼承 object 的事實",[530,1128,1129],{},"在記憶體的物理世界裡，他就是沒有任何外殼的二進位資料，沒有任何地方長得像 object",[551,1131,1132],{},"++++++++++++++",[1107,1134,1136],{"id":1135},"b-世界線交會當物理矛盾當場炸開","B. 世界線交會：當物理矛盾當場炸開",[551,1138,1139],{},"當你忽然手癢，寫出這行程式碼，強迫「物理上沒殼的平民」去坐「名義上老爸的皇帝位」時：",[14,1141,1143],{"className":16,"code":1142,"language":18,"meta":19,"style":19},"object obj = age; \u002F\u002F 💥 物理衝突點\n",[21,1144,1145],{"__ignoreMap":19},[24,1146,1147],{"class":26,"line":27},[24,1148,1142],{},[542,1150,1151,1154],{},[530,1152,1153],{},"左邊的 object obj：在 【Stack 區】 宣告了一個空皮包（指針變數），它規定自己只能收納 【Heap-Heap 區的大樓門牌（地址）】，且要求大樓門口必須有標準外殼結構（Object Header）。",[530,1155,1156],{},"右邊的 age：躺在 【Stack 區】 的純資料，沒有門牌地址讓別人追蹤，更沒有外殼結構。\n皮包無法直接綁定一個沒殼且沒門牌的資料，為了不讓 CPU 順著指針衝進 Stack 撞牆，CLR 必須強制啟動 Boxing 施工隊進行物理轉譯。",[1107,1158,1160],{"id":1159},"c-裝箱boxing的四步施工作業","C. 裝箱（Boxing）的四步施工作業",[542,1162,1163,1166,1169,1172],{},[530,1164,1165],{},"區圈地：CPU 衝進 【Heap-Heap】 區大喊：「快給我撥一塊全新大樓的空間！」",[530,1167,1168],{},"蓋出標準外殼：在這塊地上焊上 System.Object 規格的指針外殼（Object Header + Method Table 指針），符合 obj 皮包的挑剔胃口。",[530,1170,1171],{},"複製肉身：把 Stack 區 age 肚子裡的 25 影印一份，塞進 Heap-Heap 這棟新外殼大樓的客廳裡。",[530,1173,1174],{},"發放門牌並收納：新大樓在 Heap-Heap 產生了合法的實體地址門牌（例如 0x9FFF），最後把這個門牌寫進 Stack 區的 obj 皮包裡。",[551,1176,1008],{},[1178,1179,1180],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":19,"searchDepth":33,"depth":33,"links":1182},[1183,1187],{"id":12,"depth":33,"text":12,"children":1184},[1185,1186],{"id":525,"depth":39,"text":525},{"id":892,"depth":39,"text":893},{"id":907,"depth":33,"text":908,"children":1188},[1189,1190,1191,1192,1193],{"id":911,"depth":39,"text":911},{"id":954,"depth":39,"text":955},{"id":1011,"depth":39,"text":1012},{"id":1037,"depth":39,"text":1038},{"id":1101,"depth":39,"text":1102},"backend","2026-08-09","\u002F\u002F WorkItem implicitly inherits from the Object class.",false,"md",{},"\u002Fnotes\u002Fsync\u002Fcsharp-02",{"title":5,"description":1196},"C#\u002F易混淆概念\u002F易混淆概念02.md","notes\u002Fsync\u002Fcsharp-易混淆概念-易混淆概念02",[1205,1206],"C#","Concepts","aUkXACHJgMk2oqo8LYLFiKqd0VRueGre-u64DvAdE5E",1788767747505]