Каб выкарыстоўваць ўласцівасць толькі для чытання або метад?

Мне трэба, каб выкрыць « адлюстроўваецца? » стан асобніка класа. Вынік вызначаецца асноўны праверкі. Гэта <�моцны> не проста выстаўляючы значэнне поля. Я не ўпэўнены, ці варта я выкарыстаць ўласцівасць толькі для чытання або метад.

<�Моцны> Уласцівасць толькі для чытання:

public bool IsMapped
{
    get
    {
        return MappedField != null;
    }
}

<�Моцны> Метад:

public bool IsMapped()
{
    return MappedField != null;
}

Я прачытаў MSDN па Выбар паміж ўласцівасцямі і метадамі , але Я да гэтага часу не ўпэўнены.

67
Я думаю, sysexpands каментар у адказ Джэймс ваш адказ. Калі вы азірацца назад на код або іншых распрацоўшчыкаў глядзець на яго; маючы яго як ўласцівасць амаль напэўна паказвае, што ён вяртае толькі значэнне, якое адносіцца да поля. Ні адзін разважны распрацоўшчык не паставіў б залішнюю функцыянальнасць у праве ўласнасці? З іншага боку, 10 адказаў усе кажуць RO ўласнасць, безумоўна, той жа адказ
дададзена аўтар Sayse, крыніца
Такім чынам, што ж чытанне MappedField цягне за сабой? Гэта простае чытанне зменнай, ці гэта патэнцыйна дарагая аперацыя або адна з пабочнымі эфектамі (напрыклад, адкладзенай загрузкі)?
дададзена аўтар Michael Kjörling, крыніца

12 адказы

C # стандарт кажа

<�Р> § 8.7.4      <�Р> А <�моцны> Уласцівасць </моцны> з'яўляецца элементам, які забяспечвае доступ да характарыстыкі аб'екта або класа. Прыклады уласцівасцяў ўключаюць даўжыню радка, памер шрыфта, загаловак акна, імя кліента, і гэтак далей. Ўласцівасці з'яўляюцца натуральным працягам палёў. Абодва названыя члены з асацыяванымі тыпамі, і сінтаксіс для доступу да палёў і ўласцівасцям з'яўляецца тое ж самае. Аднак, у адрозненне ад палёў, ўласцівасці не пазначаюць месцы захоўвання. Замест гэта ўласцівасць мае аксессор, якія вызначаюць аператары, якія будуць выконвацца, калі іх значэння счытваюцца ці запісваюцца.

у той час, як метады вызначаюцца як

<�Р> § 8.7.3      <�Р> А <�моцны> метад </моцны> з'яўляецца элементам, які рэалізуе вылічэнні або дзеянні, якія могуць быць выкананы з дапамогай аб'екта або класа. Метады ёсць (магчыма, пусты) спіс фармальных параметраў, значэнне вяртання (калі вяртанне тыпу метаду; не мае юрыдычнай сілы), і з'яўляюцца статычнымі ці не статычнымі. </Р>

Properties and methods are used to realize encapsulation. Properties encapsulate data, methods encapsulate logic. And this is why you should prefer a read-only property if you are exposing data. In your case there is no logic that modifies the internal state of your object. You want to provide access to a characteristic of an object.

Ці з'яўляецца асобнік вашага аб'екта IsMapped ці не з'яўляецца характарыстыкай аб'екта. Ён змяшчае праверку, але менавіта таму ў вас ёсць ўласцівасці для доступу да яго. Ўласцівасці могуць быць вызначаны з дапамогай логікі, але яны не павінны падвяргаць логіку. Гэтак жа, як, напрыклад, згаданыя ў першай цытаце: Уявіце string.length <�код /> ўласцівасці. У залежнасці ад рэалізацыі, можа апынуцца, што гэта ўласцівасць перабірае радкі і падлічвае сімвалы. Яна таксама робіць выканаць аперацыю, але «звонку» гэта проста даць гэта ў заяве з унутраным дзяржаўным/характарыстыках аб'екта.

84
дададзена
«<�Я> Вы хочаце, каб забяспечыць доступ да характарыстыкі аб'екта .» - гэта тое, што я шукаў. Гэта найбольш поўны адказ з адпаведнымі спасылкамі MSDN. Дзякуючы.
дададзена аўтар davenewza, крыніца
+1 для факусоўкі ясна па семантыцы, а не па фармальным крытэрам
дададзена аўтар Vlad, крыніца
Хоць гэта і не жорсткі і хуткі правіла, я б, як правіла, таксама выкарыстоўваюць метад, калі час вылічэнні для вяртання маёмасцi не з'яўляецца трывіяльным. Ўласцівасці павінны неадкладна вярнуцца.
дададзена аўтар Andrew Hanlon, крыніца

Я хацеў бы выкарыстаць ўласцівасць, таму што няма ніякага рэальнага «рабіць» (дзеянне), не мае пабочных эфектаў, і гэта не занадта складаныя.

21
дададзена
Я хачу сказаць, кодэры такога «Я не выкарыстоўваю ***, таму што няма ніякіх аргументаў, чаму ж я яго нэндза» як мага часцей.
дададзена аўтар Nakilon, крыніца

I personally believe that a method should do something or perform some action. You are not performing anything inside IsMapped so it should be a property

11
дададзена

Я б пайсці на маёмасць. Галоўным чынам таму, што першы senctence на які спасылаецца MSDN-артыкулы:

<�Р> Увогуле, метады ўяўляюць дзеянні і ўласцівасці прадстаўлення дадзеных. </Р>
7
дададзена

Я думаю, што гэтая лінія ў вашай спасылцы адказ

<�Р> метады ўяўляюць дзеянні і ўласцівасці прадстаўлення дадзеных. </Р>

Там няма ніякага дзеяння тут, толькі частка дадзеных. Такім чынам, гэта ўласцівасць.

4
дададзена
Але ў тым жа святле, то чаму IEnumerable.Count() метад?
дададзена аўтар davenewza, крыніца
Але я таксама раблю дзеянне ... а нулявы праверка
дададзена аўтар davenewza, крыніца
IEnumerable.Count() не існуе. Count() з'яўляецца метад пашырэння, знаходзіцца ў статычным класе перечислимых, і 1) ўласцівасці пашырэння не існуе, і 2) Count (), верагодна, будзе шмат часу (асабліва ў складаных запытах LINQ).
дададзена аўтар Dave Van den Eynde, крыніца
Гэта робіць падлік ... (дзеянне)
дададзена аўтар James, крыніца
Вы правяраеце частка дадзеных, не выконваючы дзеянне на яго. - Калі на падставе выніку вы зрабілі нешта іншае або выканаў вапнавае ці нешта, то гэта быў бы метад.
дададзена аўтар James, крыніца
IEnumerable.Count() уяўляе сабой метад пашырэння, які ў асноўным ідзе шляхам збору і падліку змяшчае элементы. З іншага боку, IList.Count з'яўляецца уласцівасцю, паколькі ён не траверсу спісу - спіс ужо ведае свой рахунак і проста вяртае яго з ўласцівасці.
дададзена аўтар Zoran Horvat, крыніца
@sysexpand: IEnumerable.Count() гэта метад пашырэння, што гэта правільна, але адзіная прычына, чаму гэта пашырэнне <�б> метад ёсць, таму што ёсць не пашырэнне <�б> ўласцівасці . <�Код> IList.Count можа прайсці ўвесь спіс, у залежнасці ад рэалізацыі інтэрфейсу. Гэта немагчыма для інтэрфейсу, каб вызначыць яго рэалізацыі - тым не менш, можна вырашыць, ці з'яўляецца ці не поле аб'екта ў характарыстыку (дадзеныя/ўласцівасць) або аперацыю (метад).
дададзена аўтар Carsten, крыніца

У гэтым выпадку, здаецца, даволі ясна, што яна павінна быць уласнасцю. Гэта простая праверка, ніякай логікі, ніякіх пабочных эфектаў, не ўплывае на прадукцыйнасць. Яна не атрымаць значна прасцей, чым гэта праверка.

<�Моцны> Edit:

Звярніце ўвагу, што калі WAS любы з вышэй, і вы б пакласці яго ў метад, гэты метад павінен ўключаць у сябе моцны дзеяслоў, а не дапаможны дзеяслоў, як ёсць, або ёсць. Метад робіць нешта. Вы маглі б назваць яго VerifyMapping або DetermineMappingExistance ці нешта яшчэ да таго часу, як яна пачынаецца з дзеясловам.

4
дададзена
Але MappedField! = NULL па вызначэнні з'яўляецца лагічным аператар.
дададзена аўтар davenewza, крыніца
@ MichaelKjörling Відавочна, што ён мог бы рэалізаваць карыстацкі аператар! =, Якая фарматуе яго жорсткі дыск, але вы можаце разбіць ўсе, што ў многіх адносінах. Пакуль не пазначана іншае, я буду лічыць, што я бачу, гэта стандартам.
дададзена аўтар nvoigt, крыніца
Вы выкажам здагадку, што чытанне MappedField з'яўляецца простым, хуткім і не мае пабочных эфектаў. Мы не ведаем, што, каб быць праўдай.
дададзена аўтар Michael Kjörling, крыніца

Калі ў любы момант вам неабходна дадаць параметры для таго, каб атрымаць значэнне, то вам патрэбен метад. У адваротным выпадку вам неабходна ўласцівасць

3
дададзена
Калі гэта значэнне мае асноўную частку ў аб'екце, то так, мы маглі б.
дададзена аўтар Odys, крыніца
З гэтым вызначэннем, як наконт индексируемой уласнасці?
дададзена аўтар Mr47, крыніца

Я згодны з людзьмі тут, кажучы, што, паколькі ён з'яўляецца атрыманне даных, і не мае пабочных эфектаў, яна павінна быць уласнасцю.

Для таго, каб пашырыць гэта, я б таксама прыняць некаторыя пабочныя эфекты з лягавых (але не геттер), калі пабочныя эфекты мелі сэнс для каго-то «гледзячы на ​​яго з боку».

Адзін са спосабаў думаць пра гэта з'яўляецца тое, што метады з'яўляюцца дзеясловы, і ўласцівасці прыметнікаў (тым часам, самі аб'екты з'яўляюцца назоўнікі, а статычныя аб'екты абстрактных назоўнікаў).

Адзінае выключэнне дзеяслова/прыметніка дырэктывы з'яўляецца тое, што ён можа мець сэнс выкарыстоўваць метад, а не ўласцівасць пры атрыманні (альбо ўсталявання) адпаведная інфармацыя можа быць вельмі дарагім: Лагічна, такая функцыя павінна, верагодна, да гэтага часу з'яўляецца уласцівасцю, але людзі прывыклі да думкі пра ўласцівасці, як прадукцыйнасць-накрыж нізкай аддачай і ў той час як няма ніякай рэальнай прычыны, чаму гэта заўсёды павінна быць, было б карысна, каб падкрэсліць, што GetIsMapped() адносна цяжкі выканаць -wise, калі гэта на самай справе было.

На ўзроўні працуе кода, няма абсалютна ніякай розніцы паміж выклікам ўласцівасці і выклікаючы эквівалентны метад, каб атрымаць ці ўсталяваць; гэта ўсё пра тое, каб жыццё прасцей для чалавека напісання кода, які выкарыстоўвае яго.

2
дададзена

У сітуацыях/моў, дзе ў вас ёсць доступ да абодвух з гэтых канструкцый, агульны разрыў выглядае наступным чынам:

  • Калі запыт на нешта аб'ект <�ет> ёсць , выкарыстоўвайце ўласцівасць (або поле).
  • Калі запыт на вынік чагосьці аб'ект робіць , выкарыстоўвайце метад.

Ледзь больш канкрэтна, гэта ўласцівасць будзе выкарыстоўвацца для доступу, для чытання і/або запісы моды, элемент дадзеных, які (для спажывання мэтаў), якія належаць аб'екту, падвяргаючы ўласцівасць. Ўласцівасці лепш, чым палёў, так як дадзеныя не павінны існаваць у пастаяннай форме ўвесь час (яны дазваляюць вам быць «лянівым» пра разліку або выманні гэтага значэння дадзеных), і яны лепш, чым метады для гэтай мэты, таму што вы можаце выкарыстоўваць іх у кодзе, як калі б яны былі адкрытымі палямі.

Ўласцівасці не павінны, аднак, прывесці да пабочным эфектам (з магчымым, зразумела выключэннем ўстаноўкі зменнай азначала захоўвацца значэнне вяртаецца, пазбягаючы дорага пераразлік значэння патрабуецца шмат разоў); яны павінны, пры іншых роўных умовах, вяртаюць дэтэрмінаваных вынік (так NextRandomNumber дрэнны канцэптуальны выбар для нерухомасці) і разлік не павінны прыводзіць да змены якіх-небудзь дадзеных аб стане, якія будуць уплываць на іншыя разлікі (напрыклад, атрыманне PropertyA і PropertyB ў такім парадку не павінен вяртаць любой іншы вынік, чым атрымліваць PropertyB, а затым PropertyA).

Спосаб, Ад, канцэптуальна разумеецца як выкананне некаторых аперацый і вяртання выніку; Карацей кажучы, ён робіць нешта, што можа пашырыць за рамкі вылічэнні вяртаецца значэння. Метады, такім чынам, павінны быць выкарыстаны, калі аперацыя, якая вяртае значэнне мае дадатковыя пабочныя эфекты. Вяртаецца значэнне па-ранейшаму можа быць вынікам некаторых вылічэнняў, але метад можа быць вылічаны яго недетерминированно (GetNextRandomNumber ()), або вяртаюцца дадзеныя ў выглядзе унікальнага асобніка аб'екта і выклік метаду зноў вырабляе іншы асобнік, нават калі гэта можа мець адны і тыя ж дадзеныя (GetCurrentStatus ()), ці спосаб можа змяніць дадзеныя аб стане, напрыклад, што рабіць тое ж самае ў два разы запар выдае розныя вынікі (EncryptDataBlock (), многія шыфры шыфравання працуюць такім чынам шляхам канструкцыя для таго каб забяспечыць шыфраванне і тыя ж дадзеныя двойчы запар вырабляе розныя шифртексты).

2
дададзена

ІМХО, першае ўласцівасць толькі для чытання з'яўляецца правільным, таму што IsMapped як атрыбут вашага аб'екта, і вы не выконваеш дзеянне (толькі ацэнку), але ў канцы дня consistancy з існуючым кодавай верагодна, мае большае значэнне, чым семантыка .... калі гэта не з'яўляецца ўні прызначэнне

2
дададзена

Я хацеў бы чакаць ўласнасць, як гэта толькі вяртае дэталь поля. З іншага боку, я б чакаць,

MappedFields[] mf;
public bool IsMapped()
{
     mf.All(x => x != null);
}
1
дададзена
У гэтым прыкладзе вы выконваеце некалькі нулявы праверку. Як гэта лагічна адрозніваецца ад маёй, дзе я таксама якая выконвае Null праверыць?
дададзена аўтар davenewza, крыніца
Яго рознае, як вы не ведаеце адказ, пакуль вы не queryed кожнага члена мкф
дададзена аўтар Sayse, крыніца

Вы павінны выкарыстоўваць ўласцівасць, таму што C# маюць ўласцівасць па гэтай прычыне

0
дададзена