[問題] 新手學C#,有關{get;set;}的疑問

看板C_Sharp (C#)作者 (孤單ㄉ翼)時間10年前 (2014/12/11 20:04), 10年前編輯推噓5(5047)
留言52則, 7人參與, 最新討論串1/5 (看更多)
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

12/11 20:16, , 1F
第二個問題好像就是第一個問題的延伸
12/11 20:16, 1F

12/11 20:18, , 2F
第一個問題,那是變數只是他可以分別對讀與寫作不同處理
12/11 20:18, 2F

12/11 20:18, , 3F
比如說我可以設定{get; private set;}
12/11 20:18, 3F

12/11 20:19, , 4F
只有內部可以設定這個屬性,對外部來說這就是唯獨屬性
12/11 20:19, 4F

12/11 20:20, , 5F
我應該要講屬性,怎麼會講變數
12/11 20:20, 5F

12/11 20:21, , 6F
這樣的寫法比我寫function要分別寫讀跟寫要快多了
12/11 20:21, 6F

12/11 20:22, , 7F
不好意思,我不太懂理論,只就我自己運用上的感覺來說
12/11 20:22, 7F

12/11 20:25, , 8F
第二個問題好像就需要更深的講解,只能等懂得人來說了
12/11 20:25, 8F

12/11 21:17, , 9F
Q1: auto-implemented property, 編譯器會幫你處理
12/11 21:17, 9F

12/11 21:18, , 10F
至於初始值的問題,在C# 6將可以對auto-property設初始值
12/11 21:18, 10F

12/11 21:23, , 11F
先拋開所謂"傳統的"的Java寫法,直接從C#的角度來看
12/11 21:23, 11F

12/11 21:27, , 13F
這邊是微軟對於使用 property 的 guideline.
12/11 21:27, 13F

12/11 22:04, , 14F
補充樓上的,你每個屬性都要寫get set不是很麻煩嗎?
12/11 22:04, 14F

12/11 22:05, , 15F
所以微軟讓你有簡短的寫法,編譯器會寫麻煩的地方
12/11 22:05, 15F

12/11 22:05, , 16F
所以兩種東西是一樣的
12/11 22:05, 16F

12/11 22:10, , 17F
get的時候你可以給他初值,但簡寫就無法
12/11 22:10, 17F

12/11 22:11, , 18F
上面這句剛好就是你的Q2
12/11 22:11, 18F

12/11 22:12, , 19F
另外是個人觀點,我不覺得簡寫會讓程式碼走味
12/11 22:12, 19F

12/11 22:12, , 20F
除了程式碼容易看(get set加起來才一行)
12/11 22:12, 20F

12/11 22:12, , 21F
還有就是讓能產出更有效率
12/11 22:12, 21F
我發現我講太多廢話,重點有點跑掉 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

12/11 23:39, , 22F
就說要跳脫所謂的傳統,想想 property 對 C# 物件的意義
12/11 23:39, 22F

12/11 23:40, , 23F
哪些東西該是 property, 哪些東西應該是 method
12/11 23:40, 23F

12/11 23:40, , 24F
多少會有些譜
12/11 23:40, 24F
意義是指節省程式碼? Q2那種狀況好像改成property也沒省到 Q.Q ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 00:08:09

12/12 00:13, , 25F
我覺得你不要一直把屬性(property) 和 member var
12/12 00:13, 25F

12/12 00:14, , 26F
拉上關係,屬性是我們這個類別的"外貌",
12/12 00:14, 26F

12/12 00:16, , 27F
使用這個類別的人可以改變我們的外貌,
12/12 00:16, 27F

12/12 00:16, , 28F
所以才會分出Field和Property,因為我們希望可以保留
12/12 00:16, 28F

12/12 00:17, , 29F
我們這個類別的隱私
12/12 00:17, 29F

12/12 00:23, , 30F
auto-implement property可以對get/set分別設存取權限,跟
12/12 00:23, 30F

12/12 00:24, , 31F
單純的field不一樣,另外即使一開始的確沒有其他邏輯
12/12 00:24, 31F

12/12 00:24, , 32F
先寫成property,以後要加邏輯時再implement get/set即可
12/12 00:24, 32F

12/12 00:25, , 33F
如果一開始就直接存取field,到時候就改到死...
12/12 00:25, 33F

12/12 00:26, , 34F
再來getter/setter的用途不止在給外部存取時的介面
12/12 00:26, 34F

12/12 00:26, , 35F
而是跟field比起來,可以有機會控管讀寫時的行為
12/12 00:26, 35F

12/12 00:29, , 36F
例如最常見的在讀寫時發出event
12/12 00:29, 36F

12/12 00:30, , 37F
再來你說的傳統寫法,C#才沒那種傳統,那是java的傳統吧
12/12 00:30, 37F

12/12 00:31, , 38F
跟那種把特殊命名的method定義叫property規格,然後用
12/12 00:31, 38F

12/12 00:33, , 39F
reflection時因為case/底線命名不一出一堆問題比起來
12/12 00:33, 39F

12/12 00:33, , 40F
C#直接把property定在語言裡,relfection時property直接跟
12/12 00:33, 40F

12/12 00:36, , 41F
method分開,你不覺得比較好? 那種易出錯的傳統哪邊好?
12/12 00:36, 41F

12/12 00:37, , 42F
不要一直從實作去想用method/field也一樣還怎樣
12/12 00:37, 42F

12/12 00:38, , 43F
使用property最大的目的就在表明是個property
12/12 00:38, 43F
沒說是C#傳統阿 只是印象中傳統(?)OO是這樣 XD 大概了解了,把property當成獨立於method和field的object第三個元素 而不要一直把他看成是為了簡寫Get / Set的存在 是這樣的意思嗎? ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 00:44:36

12/12 01:11, , 44F
其實從OO角度來看,我覺得method/property才是介面元素
12/12 01:11, 44F

12/12 01:14, , 45F
field只是存data的空間,只是有些OO語言沒有提供property
12/12 01:14, 45F

12/12 01:17, , 46F
java 、 c++ 都沒有(吧)
12/12 01:17, 46F
我也覺得是介面元素,只是前幾天剛看到以為只是個省略寫法 今天要細究才發現是property,但property觀念非常薄弱 一直有些先入為主的觀念導致轉不過來 看來從PHP轉到ASP.NET要改的觀念要改很多 Q.Q ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 01:23:16

12/12 01:24, , 47F
就是這兩個沒有,所以有些學過OOP的卻沒property的概念..
12/12 01:24, 47F
PHP的OO疑似是學JAVA的所以也沒有 也許某些樣版有模擬這概念,但前公司沒使用 很久以前買的ASP.NET也沒提到 最近學ASP.NET一整個覺得好陌生(崩潰) ※ 編輯: CloudyWing (114.35.46.112), 12/12/2014 01:31:52

12/12 01:29, , 48F
很多語言有類似的寫法,C#是提供一個把name/getter/setter
12/12 01:29, 48F

12/12 01:33, , 49F
整合成單一元素的完整支援
12/12 01:33, 49F

12/13 10:43, , 50F
最重要的就是權限管理, 其他討論都是多的
12/13 10:43, 50F

12/18 09:10, , 51F
以OOP來說重點在封裝,不是在權限管理
12/18 09:10, 51F

10/19 09:30, , 52F
SO上有現成回答https://tinyurl.com/ybkykagy
10/19 09:30, 52F
文章代碼(AID): #1KYOXZgR (C_Sharp)
文章代碼(AID): #1KYOXZgR (C_Sharp)