why use getter,setter/accessor?

這是最近在想的一個(gè)問題,使用getter,setter的好處是什么? 但實(shí)際上,我在搜索的過程中,看到了很多“反對(duì)”的聲音。

先復(fù)習(xí)一下,什么是getter,setter.

在C#中,我們又稱它為property(屬性),它是一組setter,getter的訪問器(accessor),是一個(gè)函數(shù)成員。
在使用上,就像是在調(diào)用公共的字段一樣,但它是函數(shù),不分配內(nèi)存。

set訪問器為屬性賦值。擁有一個(gè)單獨(dú)的,隱式的值參,名為value,與屬性的類型相同。返回類型為void.
get訪問器從屬性獲取值。沒有參數(shù),擁有一個(gè)與屬性類型相同的返回類型。get訪問器返回一條return語句。
setter,getter可以任意順序聲明,并且,除了這兩個(gè)訪問器外,不允許有其它的方法。

如:

private stringcristiano;
    public string Cristinao{
        set{ cristiano = value; }
        get{ return cristiano; }
        age{...}//error
    }
屬性常和字段進(jìn)行關(guān)聯(lián),字段通常設(shè)置為private(這通常叫”后備字段“),因?yàn)槊嫦驅(qū)ο蟮脑O(shè)計(jì)的重要原則之一就是數(shù)據(jù)封裝,意味著類型的字段永遠(yuǎn)不應(yīng)該被公開,否則很容易被不恰當(dāng)?shù)氖褂米侄味茐牧藢?duì)象的狀態(tài),如:xxx.age-=5;是不合理的,所以,要通過函數(shù),來對(duì)保護(hù)的字段進(jìn)行讀寫。(很像代理設(shè)計(jì)模式:))

在屬性中,可以做很多邏輯上的計(jì)算,比如:

private int money;
    public int Money{
        set{ 
            money = value < 100 ? 100 : value;
        }
        get{
            return money < 100 ? 100 : money;
        }
    }

屬性始終是函數(shù)成員。

getter,setter并不需要同時(shí)定義,只包含getter的屬性,只能讀取,而不能寫入,相反,只包含setter的屬性,只能寫入,不能讀取,但兩者必須至少定義一個(gè)。

自動(dòng)實(shí)現(xiàn)屬性

因?yàn)閷傩越?jīng)常被關(guān)聯(lián)到”后備字段“,C#提供了自動(dòng)實(shí)現(xiàn)屬性(AIP),允許只聲明 屬性 而不需要聲明 后備字段
,編譯器會(huì)為你隱藏的創(chuàng)建一個(gè)私有的字段,并且自動(dòng)掛接到get和set訪問器上(accessor)

如:

public string Messi {
        set;
        get;
    }
如果其中一個(gè)訪問器提供了方法體,另一個(gè)也需要。
public static string Russia {
        set;
        get;
    }
什么時(shí)候應(yīng)該使用字段?

1.你希望返回字段來執(zhí)行一些其它的副作用,比如緩存某個(gè)值(currentState,PreviousState)
2.你希望以線程安全的方式來訪問字段
3.這是一個(gè)邏輯的字段,需要計(jì)算來獲得,如面積area.

基礎(chǔ)說完了,那么以上面定義的Russia為例,他和常規(guī)定義一個(gè)set,get函數(shù)有什么優(yōu)勢(shì)呢?

private string russia;
    public void SetRussia(string val)
    {
        russia = val;
    }

    public string GetRussia()
    {
        return russia;
    }

首先:

最直觀的是屬性/訪問器比常規(guī)函數(shù),代碼上更加的簡(jiǎn)潔了,無論是定義上,還是使用上。

但僅僅就是這些嗎,所以常規(guī)操作,去stackoverflow上找找大神們的回復(fù),但意外的是,有很多人抨擊accessor的設(shè)計(jì)是evil.有興趣可以看下面的鏈接:
https://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html

CLR via C#的作者也對(duì)accessor的設(shè)計(jì)嗤之以鼻,不過他提到AIP自動(dòng)屬性無法調(diào)試和序列化&反序列化是不準(zhǔn)確的,也許和他的應(yīng)用環(huán)境有關(guān),我在Mono里測(cè)試,都是OK的:)

具體關(guān)于getter,setter的討論可以看這篇(很精彩):
https://stackoverflow.com/questions/1568091/why-use-getters-and-setters-accessors

有的人說,setter/getter,讓代碼不易于閱讀,你無法直接判斷是共公的字段還是屬性。
使用常規(guī)自定義的setxx/getxxx,具有更好的移植性。

屬性/訪問器,除了在使用和定義上,相比常規(guī)函數(shù)要更簡(jiǎn)潔以外,它通常于需要做一些額外操作的情況,比如校驗(yàn),保存舊的值,做一些邏輯上的計(jì)算等等,如果僅僅是返回源引用的形式,意義并不大。大多數(shù)情況下,我們還是要使用自定義參數(shù)的函數(shù)來適應(yīng)各種復(fù)雜的場(chǎng)景。(2018.9.10 更新)

參考資料:
C#圖解教程
CLR via C#

寫得有些倉促,后面看到相關(guān)的會(huì)繼續(xù)補(bǔ)充上來,2點(diǎn)15分了,時(shí)間過得太快,肚子又餓了,一堆任務(wù)壓著沒有完成,現(xiàn)在休息,早起繼續(xù)工作!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,260評(píng)論 8 265
  • 前言 人生苦多,快來 Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,703評(píng)論 9 118
  • 37.cocoa內(nèi)存管理規(guī)則 1)當(dāng)你使用new,alloc或copy方法創(chuàng)建一個(gè)對(duì)象時(shí),該對(duì)象的保留計(jì)數(shù)器值為1...
    如風(fēng)家的秘密閱讀 958評(píng)論 0 4
  • 1. load 與 initialize load:是當(dāng)類或分類被添加到 Objective-C runtime ...
    杰克道長閱讀 1,470評(píng)論 0 3
  • 1.1 spring IoC容器和beans的簡(jiǎn)介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,851評(píng)論 2 22

友情鏈接更多精彩內(nèi)容