看板 C_Sharp 關於我們 聯絡資訊
Q1: 一般在寫class的時候,為了避免直接存取member variable 都會將他設為private或是protected 然後提供Get/Set的method來讓其他人存取 後來看到C#提供Property來簡化這步驟,程式碼大概如下: ================================================== private String Text1 = ""; public String textValue { set { Text1 = value; } get { return Text1; } } ================================================== 當下看到的想法是這個寫法變得好簡潔 可是當我看到更進一步的簡化時,則開始有疑惑 =================================================== public String Text1 { get; set; } =================================================== 這樣Text1到底應該算是個method還是member variable? 雖然說Text1本身不會存取變數,而是另外將值存取到隱藏(?)的變數 但class本身並沒有對應member variable,Text1也沒有定義對應變數 那Text1是否就等於是變相成為此class的member variable? 然後當你不希望Text1只能get或是只能set時 會發現你只寫get,但是你無法給他初始值,所以沒意義 如果只寫set時,會發現沒有任何人可以存取他 (這部分不確定,有錯請指認) 所以有點疑惑當簡寫到這種程度的時候是否有其意義? Q2: 今天看程式書時看到他在製作取得appSetting的method時是這樣寫 ========================================================== public static String KeyName() { get { return System.Web.Configuration. WebConfigurationManager.AppSettings["KeyName"]; } } =========================================================== 當下看到很疑惑的是這只是取得AppSettings的設定 是否有必要特地採用Property的寫法? 感覺就只是變相取一個比較短名稱的method而已 那用傳統的寫法是否會比較適當? =========================================================== public static String getKeyName() { return System.Web.Configuration. WebConfigurationManager.AppSettings["KeyName"]; } =========================================================== 會來提問主要是最近看得書和程式都是這類簡化寫法 總覺得有點走味了,但是由於剛開始學 所以也不知是否真的因某些考量,所以這樣寫比較好 還是單純覺得寫法比較簡短才這樣寫 請前輩們指導一下 Q.Q -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.35.46.112 ※ 文章網址: http://www.ptt.cc/bbs/C_Sharp/M.1418299491.A.A9B.html
Peruheru: 第二個問題好像就是第一個問題的延伸 12/11 20:16
Peruheru: 第一個問題,那是變數只是他可以分別對讀與寫作不同處理 12/11 20:18
Peruheru: 比如說我可以設定{get; private set;} 12/11 20:18
Peruheru: 只有內部可以設定這個屬性,對外部來說這就是唯獨屬性 12/11 20:19
Peruheru: 我應該要講屬性,怎麼會講變數 12/11 20:20
Peruheru: 這樣的寫法比我寫function要分別寫讀跟寫要快多了 12/11 20:21
Peruheru: 不好意思,我不太懂理論,只就我自己運用上的感覺來說 12/11 20:22
Peruheru: 第二個問題好像就需要更深的講解,只能等懂得人來說了 12/11 20:25
iterator: Q1: auto-implemented property, 編譯器會幫你處理 12/11 21:17
iterator: 至於初始值的問題,在C# 6將可以對auto-property設初始值 12/11 21:18
iterator: 先拋開所謂"傳統的"的Java寫法,直接從C#的角度來看 12/11 21:23
iterator: 這邊是微軟對於使用 property 的 guideline. 12/11 21:27
GoalBased: 補充樓上的,你每個屬性都要寫get set不是很麻煩嗎? 12/11 22:04
GoalBased: 所以微軟讓你有簡短的寫法,編譯器會寫麻煩的地方 12/11 22:05
GoalBased: 所以兩種東西是一樣的 12/11 22:05
GoalBased: get的時候你可以給他初值,但簡寫就無法 12/11 22:10
GoalBased: 上面這句剛好就是你的Q2 12/11 22:11
GoalBased: 另外是個人觀點,我不覺得簡寫會讓程式碼走味 12/11 22:12
GoalBased: 除了程式碼容易看(get set加起來才一行) 12/11 22:12
GoalBased: 還有就是讓能產出更有效率 12/11 22:12
我發現我講太多廢話,重點有點跑掉 XD 剛看了一樓的唯讀的用法,再去查一下,大概懂簡寫的用意 先回過頭來看第一個簡寫的方式 可以看成把Get / Set的method包成property 利用這個property來存取member variable 以傳說OO的這個角度來說,這個簡寫法絕對沒有問題,一大福音 再看看第二個簡寫法 C#3.0新增的auto-implemented properties 他的作法變成是將原本的Get / Set method和member variable 給包成property 從外部的角度來看,這種沒加工的property變相是object的member variable 所以存取property和存取member variable是一樣的意思 我的疑問點在此,如果你已經不想管OO不讓外部直接存取member variable的原則 那這種縮寫法不如定義public member variable就好? 何必多此一舉包成property,反而沒簡寫到 所以當初想這種寫法好處就應該是設成讓外部只能only ready或only write時較好用 (這應該也是這樣縮寫的重點) 不過我之前在研究怎only ready或only write時 是把set或get省略,所以導致失敗(在此感謝一樓前輩告訴我是加上privte) 再來是Q2 結合前面來看,一般會設定property 應該要就是利用property存取member variable 或是連member variable也包成property 但Q2案例應該不屬於前兩者 比較像是常使用所以包成static method,讓下次要使用直接呼叫那類程式碼 卻因為命名習慣是get開頭而被包成property 而實際上包成property似乎也沒簡寫到 那這樣的作法是否矯枉過正? 這是我在書上這類狀況都是這樣寫的,所以覺得疑惑 ※ 編輯: CloudyWing (114.35.46.112), 12/11/2014 23:20:09 ※ 編輯: CloudyWing (114.35.46.112), 12/11/2014 23:25:16
iterator: 就說要跳脫所謂的傳統,想想 property 對 C# 物件的意義 12/11 23:39
iterator: 哪些東西該是 property, 哪些東西應該是 method 12/11 23:40
iterator: 多少會有些譜 12/11 23:40
意義是指節省程式碼? Q2那種狀況好像改成property也沒省到 Q.Q ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 00:08:09
BigLoser: 我覺得你不要一直把屬性(property) 和 member var 12/12 00:13
BigLoser: 拉上關係,屬性是我們這個類別的"外貌", 12/12 00:14
BigLoser: 使用這個類別的人可以改變我們的外貌, 12/12 00:16
BigLoser: 所以才會分出Field和Property,因為我們希望可以保留 12/12 00:16
BigLoser: 我們這個類別的隱私 12/12 00:17
ssccg: auto-implement property可以對get/set分別設存取權限,跟 12/12 00:23
ssccg: 單純的field不一樣,另外即使一開始的確沒有其他邏輯 12/12 00:24
ssccg: 先寫成property,以後要加邏輯時再implement get/set即可 12/12 00:24
ssccg: 如果一開始就直接存取field,到時候就改到死... 12/12 00:25
ssccg: 再來getter/setter的用途不止在給外部存取時的介面 12/12 00:26
ssccg: 而是跟field比起來,可以有機會控管讀寫時的行為 12/12 00:26
ssccg: 例如最常見的在讀寫時發出event 12/12 00:29
ssccg: 再來你說的傳統寫法,C#才沒那種傳統,那是java的傳統吧 12/12 00:30
ssccg: 跟那種把特殊命名的method定義叫property規格,然後用 12/12 00:31
ssccg: reflection時因為case/底線命名不一出一堆問題比起來 12/12 00:33
ssccg: C#直接把property定在語言裡,relfection時property直接跟 12/12 00:33
ssccg: method分開,你不覺得比較好? 那種易出錯的傳統哪邊好? 12/12 00:36
ssccg: 不要一直從實作去想用method/field也一樣還怎樣 12/12 00:37
ssccg: 使用property最大的目的就在表明是個property 12/12 00:38
沒說是C#傳統阿 只是印象中傳統(?)OO是這樣 XD 大概了解了,把property當成獨立於method和field的object第三個元素 而不要一直把他看成是為了簡寫Get / Set的存在 是這樣的意思嗎? ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 00:44:36
ssccg: 其實從OO角度來看,我覺得method/property才是介面元素 12/12 01:11
ssccg: field只是存data的空間,只是有些OO語言沒有提供property 12/12 01:14
BigLoser: java 、 c++ 都沒有(吧) 12/12 01:17
我也覺得是介面元素,只是前幾天剛看到以為只是個省略寫法 今天要細究才發現是property,但property觀念非常薄弱 一直有些先入為主的觀念導致轉不過來 看來從PHP轉到ASP.NET要改的觀念要改很多 Q.Q ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 01:23:16
ssccg: 就是這兩個沒有,所以有些學過OOP的卻沒property的概念.. 12/12 01:24
PHP的OO疑似是學JAVA的所以也沒有 也許某些樣版有模擬這概念,但前公司沒使用 很久以前買的ASP.NET也沒提到 最近學ASP.NET一整個覺得好陌生(崩潰) ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 01:31:52
ssccg: 很多語言有類似的寫法,C#是提供一個把name/getter/setter 12/12 01:29
ssccg: 整合成單一元素的完整支援 12/12 01:33
uranusjr: 最重要的就是權限管理, 其他討論都是多的 12/13 10:43
ssccg: 以OOP來說重點在封裝,不是在權限管理 12/18 09:10
fallingleaf: SO上有現成回答https://tinyurl.com/ybkykagy 10/19 09:30