Re: [問題] C#的一個List和Array的問題

看板Programming作者 (我正在想要換什麼)時間10年前 (2015/01/06 15:56), 編輯推噓2(200)
留言2則, 2人參與, 最新討論串2/3 (看更多)
※ 引述《jamod (jasper)》之銘言: : 應該是有關記憶體的問題,但上網找了一些說明,還是不是很了解 : ============================================= : public struct s_Test{ : public int i; : } : 上面是我自訂的一個struct : ======================================================= : s_Test t = new s_Test(); : List<s_Test> list = new List<s_Test>(); : list.Add(t); : list[0].i = 10; : 當我用上面的方法修改list[0].i的值會出錯, 因為 list[0] 實際上是呼叫 List class 的 indexer get method 它是個 function call 會回傳整個 struct 的複本 (因為 C# 無法回傳 ref) 當你對複本修改內容,對原本存在 List 中的 struct 毫無效果 既然無效果,compiler 乾脆把它擋下來,避免 programmer 誤會它有效 : 看說明是叫我new一個新的struct直接覆蓋list[0] : 所以我改成: : =========================================================== : List<s_Test> list = new List<s_Test>(); : list.Add(t); : s_Test temp = new s_Test(); : temp.i = 10; : list[0] = temp; : 上面這樣才可以變更裡面的值,但是我改成陣列來儲存: 這邊之所以可以直接變更值,是因為它呼叫到 List class 的 indexer set method 它也是個 function call,會把 temp 整個當參數傳進去,把原本的 struct 蓋掉 所以當你只想修改 struct 中的單一欄位時 必需要寫三行 s_Test temp = list[0]; temp.i = 10; list[0] = temp; 這是 C# 語言本身的限制 : =========================================================== : s_Test[] array = new s_Test[10]; : array[0] = t; : array[0].i = 10; : 就可以直接修改i了,想請問有沒有高手能夠解釋原因? : 非常感謝! 至於 array 就不是一個 class,而是語言本身提供的功能 使用 indexer 取值與 function call 無關 對 array[i] 做的操作完全對應到 array 中的 struct 就像你直接使用那個 struct 一樣 因此直接用 array[0].i 也沒問題 如果你研究過 C++ 的 l-value / r-value / reference 再看到這個現象會比較容易理解 C# 稍微犧牲了一點彈性 但加強了記憶體的安全 (不會有 dangling reference) -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.250.32.97 ※ 文章網址: http://www.ptt.cc/bbs/Programming/M.1420530966.A.A2A.html

01/06 17:03, , 1F
喔喔!非常感謝!解釋得很清楚了呢!
01/06 17:03, 1F

01/07 11:22, , 2F
01/07 11:22, 2F
文章代碼(AID): #1KgvKMeg (Programming)
討論串 (同標題文章)
文章代碼(AID): #1KgvKMeg (Programming)