Problem: having to declare a backing field when adding custom logic to getter and/or setter of a property. Current situation: private string ...
Skiptocontent
{{message}}
dotnet
/
roslyn
Public
Notifications
Fork
3.6k
Star
15.7k
Code
Issues
5k+
Pullrequests
395
Discussions
Projects
44
Security
Insights
More
Code
Issues
Pullrequests
Discussions
Projects
Security
Insights
Newissue
Haveaquestionaboutthisproject?SignupforafreeGitHubaccounttoopenanissueandcontactitsmaintainersandthecommunity.
Pickausername
EmailAddress
Password
SignupforGitHub
Byclicking“SignupforGitHub”,youagreetoourtermsofserviceand
privacystatement.We’lloccasionallysendyouaccountrelatedemails.
AlreadyonGitHub?
Signin
toyouraccount
Jumptobottom
[C#feature]Auto-propertysyntaxforcustomsetter/getterlogic.
#1551
Closed
dsafopenedthisissue
Mar24,2015
·16comments
Closed
[C#feature]Auto-propertysyntaxforcustomsetter/getterlogic.
#1551
dsafopenedthisissue
Mar24,2015
·16comments
Labels
Area-LanguageDesign
Discussion
FeatureRequest
Comments
Copylink
dsaf
commented
Mar24,2015
Problem:havingtodeclareabackingfieldwhenaddingcustomlogictogetterand/orsetterofaproperty.
Currentsituation:
privatestring_name;//Onlyusedbyproperty.
publicstringName
{
get
{
Prepare(_name);
return_name;
}
set
{
PreProcess(value);
_name=value;
PostProcess(value);//...orshouldwepass_name?Ambiguityfordevelopers.
}
}
Suggestedchange:
publicstringName
{
get
{
Prepare(value);
returnvalue;
}
set
{
PreProcess(value);
applyvalue;
PostProcess(value);
}
}
TypicalWPFscenarioafterchange:
publicstringName
{
get;
set
{
applyvalue;
OnPropertyChanged();//Uses[CallerMemberName]orsomething,haven'ttriedit.
}
}
Crazylambdaversion(separateissue?):
publicstringName{get;setOnPropertyChanged;}//Setlambda(reducedtomethodgrouphere)isalwaysexecutedlastandisalwayspassedthevalue(isbasicallyanAction).
Questions/comments:
Isthisworthit,generally?Simplernon-AOPWPF/XAMLViewModel-s?Anyothercommonscenarios?
Isaddinganewkeyword'apply'(oppositeof'return')worthit?
Doesthesuggestedchangelookgoodenoughwhenusedtogetherwithauto-propertyinitializers?
Maybewesimplyneedtokeepfieldsclosetopropertiesonsyntaxlevel?
publicstring_nameName
{...}
Otherideasinolderdiscussion:https://roslyn.codeplex.com/discussions/550266
Thetextwasupdatedsuccessfully,buttheseerrorswereencountered:
👍
2
theoy
added
FeatureRequest
Area-LanguageDesign
labels
Mar25,2015
Copylink
KalitaAlexey
commented
Mar25,2015
Ithink#850isbetter
Sorry,somethingwentwrong.
Copylink
Author
dsaf
commented
Mar25,2015
@KalitaAlexeyIdisagree:
Theissueseemstoberegardingspecificallynon-autoproperties,especiallygiventhecommentslike"Idisagreeaddinganewkeyword,firstitwilllimitonepropertyhasonlyonefield".
Syntaxoptionsdiscussedtherearequitestrangeandsoundlikecreatingmini-classesoutofproperties,e.g."MyProperty.initialValue=;".What'snext-addingproperty-scopedmethodsandnestedtypes?
It'sverysubjectivebutformethe'field'keywordisfocusingonmanagingthefield,while'apply'isfocusingonassigningthevaluetoproperty,whichismorepreferablewhenreasoningaboutauto-properties.
Sorry,somethingwentwrong.
dsaf
mentionedthisissue
Mar25,2015
Proposal:Property-scopedfields
#850
Closed
dsaf
changedthetitle
[C#feature][Discussion]Auto-propertysyntaxforcustomsetter/getterlogic.
[C#feature]Auto-propertysyntaxforcustomsetter/getterlogic.
Mar25,2015
Copylink
KalitaAlexey
commented
Mar25,2015
@dsaf
Ifyouwanttouseseveralfieldsinpropertygettersandsetters,thenwriteitexplicit
publicstringFullName
{
get
{
returnlastName+""+firstName;
}
}
IthinksyntaxwhichIsuggestedisstraightandnotconfusing
Sorry,somethingwentwrong.
Copylink
Author
dsaf
commented
Mar25,2015
@KalitaAlexeyOuropinionsaregettingsubjectiveatthisstage.Iguessit'suptoRoslynteamnowtodecide.Theimportantthingisthatwehavepointedoutaproblemandproposedseveraldifferentsolutions.
Sorry,somethingwentwrong.
Copylink
KalitaAlexey
commented
Mar25,2015
@dsafIt'stoohardtodecide,becausetherearemanysolutions.
Oneofthem:
publicstringName
{
get;
beforeset
{
if(field==value)
returnfalse;
}
set;
afterset
{
RaisePropertyChanged(nameof(Name));
}
}
Butproblemofadditionnewkeywordsalsoishard
Sorry,somethingwentwrong.
Copylink
Author
dsaf
commented
Mar25,2015
@KalitaAlexeybythewaythereisnoneedtopass"nameof(Name)"anymore:
http://grenangen.se/node/75
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute%28v=vs.110%29.aspx
Sorry,somethingwentwrong.
Copylink
bondsbw
commented
Mar25,2015
@dsafJusttobefair,someofthesyntaxissuesyoudescribeabout#850relatetothecommentsbutnottotheactualproposal.Also,thatproposal'sfocusisonencapsulatingthebackingfield,whichisnotexplicitlythegoalofyourissue.
Thatsaid,Iappreciatewhatyouareproposing.Ifeelitisanorthogonalconcern,addingsimplebehaviorstoautomaticpropertyaccessors.
TwothingsI'mnotclearon:
Howwouldyour"Crazylambdaversion"syntaxdistinguishbetweenPrepare,PreProcess,andPostProcessitems?
IsthereanywayforPreProcesstopreventthesetfromoccurring?Forexample,onlyallowingavaluetobesetonce:
publicTelephonePhone
{
get{return_phone;}
set
{
if(_phone==null)
{
_phone=value;
}
}
}
Sorry,somethingwentwrong.
Copylink
Author
dsaf
commented
Mar25,2015
@bondsbwThatwouldbemorefair,agreed.Thereisanelementoforthogonality,true.Notbeing"forced"tokeepbackingfields"close"topropertiesissomethingthatbothersmeaswell-evenfromthesimplecodeformattingpointofview(tokeepallfieldsatthetopofthetypeornot?).
"Crazylambdaversion"wouldonlyallowaPostProcessitem.Thisisverycontroversial,Iknow.Someonewouldneedtoassessthemosttypicalusecases,tosayifit'sareasonablesimplification.IwascomingfromtheINotifyPropertyChangedscenario.
TheonlywayIcouldthinkofisdemandingthat'applyvalue'beasimplestatementthathastobepresentsomewhereonthe"firstlevel"ofthesettersbody(similartohowreturningavalueisenforcedforgetters).Anythingmorecomplicatedandusingabackingfieldstartstosoundmorereasonable.
Sorry,somethingwentwrong.
Copylink
momijin
commented
Mar25,2015
@dsaf@KalitaAlexey
Ialsowriteoneofthem:
publicTPropertyName
{
get(Funcprepare);
set(FuncpreProcess,ActionpostProcess);
}
Asetaccessorisalsoabletotakenasfollows:
set(FuncpreProcess);
set(ActionpostProcess);
example:
publicstringName
{
get(currentValue=>currentValue??newstring());
set((oldValue,newValue)=>oldValue!=newValue,(oldValue,newValue)=>OnPropertyChanged());
}
Aboveisexpandedtobycompiler:
privatestring_name;
publicstringName
{
get
{
Funcprepare=currentValue=>currentValue??newstring();
_name=prepare(_name);
return_name;
}
set
{
FuncpreProcess=(oldValue,newValue)=>oldValue!=newValue;
ActionpostProcess=(oldValue,newValue)=>OnPropertyChanged();
if(preProcess(_name,value))
{
stringoldValue=_name;
_name=value;
postProcess(oldValue,_name);
}
}
}
@bondsbw
IthinkthatProperty-scopedfields#850isaveryniceidea,whichmakesitwherefieldsshouldbe.InsimplecaseIuseAuto-propertysyntax.Butwhenitisn'tso,IwilluseProperty-scopedfields.IwishthatC#7willsupportit.
Sorry,somethingwentwrong.
Copylink
yume-chan
commented
Mar25,2015
Theapplykeyword:I'musingauto-propertysowhyIstillneedtosetbackingfieldbymyself?
Iprefer@KalitaAlexey'swaysoget;set;stillindicatesit'sanauto-propertyandbefore/afterget/set;canaddcustomlogictoit.
setOnPropertyChanged;:Ithinkifitwillbeaddedtostandard,itshouldprovideacustommethodtotakecontrolallthesettingprocess,inanotherwordsit'sjustashort-handforset{SetValue(value,nameof(Property));}(Andget{returnGetValue(nameof(Property));})(Soit'snotanauto-property)andit'seasiertounderstand.(Mentionedintheolddiscussion,butIthinkusespaceisbetter).
@dsafsaid:
Syntaxoptionsdiscussedtherearequitestrangeandsoundlikecreatingmini-classesoutofproperties,e.g."MyProperty.initialValue=;".What'snext-addingproperty-scopedmethodsandnestedtypes?
Ithinkit'slikeJavaScript,everythingisanobjectsotheycanhavetheirownfields,Itaddsmorerelevancebetweenthepropertyandfieldsaffectsit.AndinC#werestrictonlypropertiescanhavefieldsoitwon'tcausemoremassbecausewealreadyhaveclasses.
Differencefrom#850:Wehavecustompropertyandauto-property,sowehavethisissueand#850,fromdifferentstartingpoint.
Problems
Ifusingbeforeset;,canIeditfield(thekeywordreferencescompilergeneratedbackingfield)orvaluetosetfullycustomvalue?ORwhenusingapplykeyword,canIapplyacustomvalue?
Ifwecanfullycontrolthelogic,Maybesomeonewillcreateacustompropertywithautogeneratedbackingfield,isitokorisitwewanted?(Itmightbemostimportant).
WhenusingsetSomeMethod;(mentionedabove,notfirstpostver,SomeMethodwillsetvalueusingsomeotherway),whatargumentsshouldbepassedintothemethod?
Sorry,somethingwentwrong.
Copylink
KalitaAlexey
commented
Mar26,2015
Ithinkno.Imean"beforeset"musthaveonepurpose-checkavailabilityofpropertyassignment.
Iamnotsurehowhardtoimplementthis,butIwouldpreferthis"Ifbackingfieldisusedingetterorinsetter,thengeneratebackingfield.".AndIamnotsurebutIthinkbackingfieldmustbeusedingetterandinsetter.Ihavenoexampleofusingbackingfieldonlyinoneofthem.
Ilookedatexample@momijinandIstillthinkwaywith"before/afterset"isbetter.Causelambdasyntaxcannotbedebugged.Icanplaceabreakpointinsideget.Inlambdaversionitisimpossible
classPerson
{
publicstringName
{
get
{
returnfield??(field=newstring());
}
beforeset
{
if(field==value)
break;
}
set;
afterset
{
OnPropertyChanged();
}
}
}
AlsoIthinkwillbecoolIfI'llcanwritesomethinglikethis,butIunderstanditveryhardtoimplementandalsoitisnewkeywords,butthisisreallyusefulandsimpletowriteandunderstand.
classPerson
{
publicstringName
{
get
{
returnfield??(field=newstring());
}
beforesetchecknotequal;
set;
aftersetnotify;
}
}
Sorry,somethingwentwrong.
Copylink
jbjoshi
commented
Mar27,2015
Howaboutfollowingsyntax:
//Standardproperty
publicstringDefaultProperty{get;set;}usingDefaultPropertyProvider;
//Not-nullableproperty
publicstringNotNullableProperty{get;set;}usingNotNullablePropertyProvider;
//INPCproperty
publicstringInpcProperty{get;set;}usingInpcPropertyProvider;
Followingisaveryroughversionof'wouldbeimplementation':
Systemclasses:
//Propertyinformationrelatedtocurrentproperty
publicstructPropertyProviderContext{
//Objectoftypethatthepropertybelongsto
publicobjectTarget;
//Nameofcurrentproperty
publicstringPropertyName;
//Existingvalueofcurrentproperty
publicTPropertyValue;
}
//Atypethjatisusedto'mutate'propertycodegeneration
publicinterfaceIPropertyProvider
{
//takesthecontext,returnsavalueorthrowsexception
TGetValue(PropertyProviderContextcontext);
//takesthecontextandnewvalue,returnsavaluethatshouldactuallybesetinproperty
TSetValue(PropertyProviderContextcontext,TnewValue);
}
Implementations:
//Standardimplementation
publicclassDefaultPropertyProvider:IPropertyProvider
{
publicTGetValue(PropertyProviderContextcontext)
{
returncontext.PropertyValue;
}
publicTSetValue(PropertyProviderContextcontext,TnewValue)
{
returnnewValue;
}
}
//Preventnullvalues
publicclassNotNullablePropertyProvider:IPropertyProviderwhereT:class
{
//Ifexistingvalueisnull,throwexception
publicTGetValue(PropertyProviderContextcontext)
{
if(context.PropertyValue==null)
{
thrownewInvalidOperationException();
}
returncontext.PropertyValue;
}
//Ifgivenvalueisnull,throwexception
publicTSetValue(PropertyProviderContextcontext,TnewValue)
{
if(newValue==null)
{
thrownewArgumentNullException();
}
returnnewValue;
}
}
//Acontractthatallowsothertypestoinvokepropertychangedeventforthistype
publicinterfaceISupportsInpcInvocation
{
voidRaisePropertyChanged(stringpropertyName);
}
//ApropertyproviderthatsupportsINotifyPropertyChangedbehavior
publicclassInpcPropertyProvider:IPropertyProviderwhereT:class
{
//Nothingspecial
publicTGetValue(PropertyProviderContextcontext)
{
returncontext.PropertyValue;
}
//Raisepropertychangedsignalifvaluesdiffer
publicTSetValue(PropertyProviderContextcontext,TnewValue)
{
if(context.PropertyValue!=newValue)
{
(context.TargetasISupportsInpcInvocation).RaisePropertyChanged(context.PropertyName);
}
returnnewValue;
}
}
Somethingmorerefinedversionofthisapproachshouldhelpcompilerwhatcodetogenerateforeachproperty.
Thoughts?
Sorry,somethingwentwrong.
Copylink
Author
dsaf
commented
Mar27,2015
@jbjoshidon'tbeoffended,butIMHOitlookslikesomethingfromWPForJava(thinkBooleanToVisibilityConverterandAbstractSingletonProxyFactoryBean)-Rubyguyscallthis"ceremony".Iwouldratheruseabackingfield.
Sorry,somethingwentwrong.
Copylink
jbjoshi
commented
Mar27,2015
@dsaf,notatall.
IAMinfluencedalotbyWPF.
Iwouldratherhavethesekindsof'extensions'for'compiler'touseinsteadofthecompilerdecidingonit'sownonwhatcodetogenerate.
Similarto'typeproviders'conceptinF#,compilerusesourclassestomakedecisions.
EDIT:
Bytheway,thereisnothinginherethat'assemblyrewriter'cannotdo.It'sjustabouthavinglanguagefeaturesextensibleoutofthebox.MorelikeAOPoutofthebox.
Sorry,somethingwentwrong.
Copylink
momijin
commented
Mar27,2015
@CnSimonChan
4.Differencefrom#850:Wehavecustompropertyandauto-property,sowehavethisissueand#850,fromdifferentstartingpoint.
Iagreetothat,too.Inthisissue,1)applykeyword,2)before/aftersetandfieldkeyword,3)lambdainget/setareappeared.Thosemademeexcitedandthesuggestionof@CnSimonChanand@KalitaAlexeyareveryinterestingtome.Ithinkthatthisissueshouldbeusefulforfuture.
Sorry,somethingwentwrong.
gafter
added
the
Discussion
label
Nov20,2015
bondsbw
mentionedthisissue
Feb17,2017
Proposal:Property-ScopedFields
dotnet/csharplang#133
Open
Copylink
Contributor
gafter
commented
Mar20,2017
Wearenowtakinglanguagefeaturediscussiononhttps://github.com/dotnet/csharplangforC#specificissues,https://github.com/dotnet/vblangforVB-specificfeatures,andhttps://github.com/dotnet/csharplangforfeaturesthataffectbothlanguages.
Sorry,somethingwentwrong.
gafter
closedthis
Mar20,2017
Signupforfree
tojointhisconversationonGitHub.
Alreadyhaveanaccount?
Signintocomment
Assignees
Nooneassigned
Labels
Area-LanguageDesign
Discussion
FeatureRequest
Projects
Noneyet
Milestone
Nomilestone
Linkedpullrequests
Successfullymergingapullrequestmayclosethisissue.
Noneyet
8participants
Youcan’tperformthatactionatthistime.
Yousignedinwithanothertaborwindow.Reloadtorefreshyoursession.
Yousignedoutinanothertaborwindow.Reloadtorefreshyoursession.