Toon posts:

OO / C# - Un-nullable pointers

Pagina: 1
Acties:

Onderwerpen


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
Een significant deel van mijn werk gaat het er in zitten dat ik bepaalde variabelen ga checken of ze wel of niet null zijn. Je schrijft een functie met wat parameters als input, en standaard zit je al weer bovenin je functie te checken of iets wel of niet null is en wat er vervolgens mee te doen als het inderdaad null is. Terwijl ik eigenlijk noch bij het vullen van de parameter noch in de functie echt behoefte had om ook eventueel een null waarde toe te kennen. Hoe vaak hebben jullie een toepassing voor een nullable DateTime of bool? Ik maar zelden (maar het is wel handig dat het kán!). Dus dat een pointer standaard nullable is is eigenlijk tegennatuurlijk want meestal wil je dat iets altijd een waarde heeft. Ik begrijp daarom ook niet waarom er niet een soort tegenhanger van de ? (zoals DateTime?) is, bijvoorbeeld een ! (gebruikt ongeveer zoals object!) waarmee je expliciet aangeeft dat het nooit een null pointer kan zijn.

Zitten daar praktische nadelen aan? Is het lastig te implementeren? Ik kan me gewoon niet voorstellen dat we het niet hebben.

iOS developer


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

BikkelZ schreef op maandag 18 juni 2012 @ 12:43:
Hoe vaak hebben jullie een toepassing voor een nullable DateTime of bool?
Een DateTime/bool zijn niet nullable; een DateTime? en bool? wel. Ik begrijp dan ook niet goed wat je met "tegenhanger" bedoelt. Ze zijn pas nullable als je dat expliciet aangeeft.
"Hoe vaak" ik daar toepassing voor heb ik nogal afhankelijk van wat ik aan 't doen ben; ik heb er een toepassing voor wanneer ik er een toepassing voor heb. Je maakt variabelen niet nullable "omdat het kan" maar wanneer je er een reden voor hebt. Als ik een bool met "unknown/unspecified" value wil hebben dan maak ik een nullable bool En anders blijft 't gewoon een gewone bool. Idem voor een DateTime; heeft een gebruiker bijvoorbeeld niets in gevuld dat is een null value een prima toegestane waarde, en anders bevat 'ie de waarde die de gebruiker heeft ingevuld. Je kunt dat ook oplossen door de variabele de DateTime.Min of DateTime.Max value te geven ofzo, maar dan zie je geen onderscheid meer tussen "niet ingevuld" of (toevallig) de exacte DateTime.Max value ingevuld. Ik doe daar niet graag aan.

Als je het hebt over non-valuetypes (e.g. reference types) die wel null kunnen zijn dan kun je een check doen; hoe eerder je dat doet hoe minder dat je dat op "diepere" functies niet (meer) hoeft te doen. Je public interface moet er gewoon voor zorgen dat alles netjes in orde is voor 't de diepere krochten van je applicatie in gaat.

Overigens is er een null coalescing operator en kun je eens kijken naar dingen als design by contract, null object pattern of AOP waarbij je bepaalde zaken makkelijk buiten de bodies van je methods kunt trekken om ze zo overzichtelijk(er) te houden.

[Voor 26% gewijzigd door RobIII op 18-06-2012 13:39]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
Dat zijn toch allemaal doekjes voor het bloeden? Allemaal niet nodig als een object referentie gewoon simpelweg nooit null zou kunnen zijn. En ik check toch regelmatig op nullvalues op verschillende niveaus, het is mij namelijk zelden duidelijk dat alleen ik aan de code werk en zal blijven werken. Iemand bouwt er een functie bij, roept de niet-gecheckte functie aan met een null pointer in productie en succes met uitzoeken maar.

iOS developer


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

BikkelZ schreef op maandag 18 juni 2012 @ 13:39:
Iemand bouwt er een functie bij, roept de niet-gecheckte functie aan met een null pointer in productie en succes met uitzoeken maar.
Dan wordt er heus wel ergens een exception gegooid. En die hoort er bij (unit)testen dan uit te komen. Die kun je vangen/afhandelen/whatever of lekker laten ploffen en zorgen dat je die method niet met een null aanroept. Het .Net framework gooit ook gewoon een NullArgumentException wanneer nodig; of de aangeroepen method dat doet of één van de interne functies die die method aanroept doet er toch niet toe?

[Voor 17% gewijzigd door RobIII op 18-06-2012 13:43]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
Maar jij vindt het dus prettig om constant checks te doen op null en je zou ook zeker nooit gebruik maken van een pointer die nooit null is? Je kunt overal wel omheen programmeren en testen, net zoals je in PHP ook zonder strong typed variabelen robuuste code kunt schrijven. Je moet je alleen afvragen of het niet beter en makkelijker kan.

Het heet niet voor niks de Billion Dollar Mistake bij de bedenker van de null pointer!

iOS developer


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

BikkelZ schreef op maandag 18 juni 2012 @ 13:44:
Maar jij vindt het dus prettig om checks te doen op null
Ja, want het geeft me de mogelijkheid om wél null te gebruiken (of "toe te staan") wanneer ik wil.
BikkelZ schreef op maandag 18 juni 2012 @ 13:44:
Je kunt overal wel omheen programmeren en testen
Ik ben van "jongs af aan" gewend defensief te programmeren. Check je "ins".
Als je een functie maakt die een gemiddelde berekent over X moet je ook controleren dat X geen 0 is (want: delen door nul is flauwekul :P ) en wanneer je een winkelwagentje bouwt moet je ook controleren dat men niet -3 items (of een belachelijk aantal als 232-1) in het wagentje stopt. Die checks doe je net zo goed. What's the difference?
BikkelZ schreef op maandag 18 juni 2012 @ 13:44:
Het heet niet voor niks de Billion Dollar Mistake bij de bedenker van de null pointer!
Elke bug kan een "billion dollar mistake" zijn. Een floating point rounding "error" net zo goed* als een null reference.
* 28 doden, 100 gewonden. Dat is eigenlijk nog veel "duurder" dan een quasi/gekscherend gedoopte "billion dollar mistake".

[Voor 6% gewijzigd door RobIII op 18-06-2012 13:53]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • Daspeed
  • Registratie: maart 2001
  • Laatst online: 20:29
DateTime en Boolean zijn structs / value types. Die kunnen niet null zijn.
MSDN: Value Types (C# Reference)

String, Array zijn classes / reference types. Die kunnen null zijn (jouw probleem vermoed ik).
MSDN: null (C# Reference)

In standaard C# is het niet mogelijk om te specificeren dat een reference niet null mag zijn. In deze uitbreiding is dat wel mogelijk:
http://research.microsoft.com/en-us/projects/specsharp/

Als je niet vast zit aan C# zou je ook naar F# kunnen kijken. Daar werkt het net allemaal iets anders:
MSDN: Options (F#)
MSDN: Null Values (F#)

  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
RobIII schreef op maandag 18 juni 2012 @ 13:48:
[...]

Ja, want het geeft me de mogelijkheid om wél null te gebruiken (of "toe te staan") wanneer ik wil.
Je kunt dan toch ObjectType gebruiken in plaats van ObjectType! als je wel wilt kunnen nullen, net zoals je DateTime? gebruikt in plaats van DateTime? Ik heb helemaal nergens gezecht dat alle pointers altijd nooit null mogen zijn, maar dat je wel moet kunnen aangeven dat iets nooit null zou mogen zijn.

Spec# ziet er wel goed uit. F# is natuurlijk wel een compleet ander idee.

[Voor 6% gewijzigd door BikkelZ op 18-06-2012 13:58]

iOS developer


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

BikkelZ schreef op maandag 18 juni 2012 @ 13:56:
[...]


Je kunt dan toch ObjectType gebruiken in plaats van ObjectType! als je wel wilt kunnen nullen, net zoals je DateTime? gebruikt in plaats van DateTime? Ik heb helemaal nergens gezecht dat alle pointers altijd nooit null mogen zijn, maar dat je wel moet kunnen aangeven dat iets nooit null zou mogen zijn.ok
En ik zeg je dat je dan eens moet kijken naar:
waar, o.a., de hiervoor genoemde Spec# ook aangehaald wordt. Wat wil je nou horen? Het is zoals het is en, nee, in "standaard" C# kun je geen non-nullable reference type maken. Wil je dat opgelost hebben dan kun je beter een ticket bij MS aanmaken ;)

Het grootste deel van 't probleem lijkt mij echter:
BikkelZ schreef op maandag 18 juni 2012 @ 12:43:
Een significant deel van mijn werk
Wat is er zoveel werk aan een:
C#:
1
2
if (null == someparam)
  throw new ArgumentNullException("someparam");

? Dus ik ben eens benieuwd hoe 't komt dat dit een significant deel van je werk is? Misschien doe je wel iets "raars"? Kun je eens een voorbeeld posten?

[Voor 32% gewijzigd door RobIII op 18-06-2012 14:04]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
Het is net zo makkelijk en zinloos als is_int of get_class gebruiken bovenin bij een PHP functie. Waardeloze rommelcode die feitelijk niks toevoegt en alleen geld kost om te onderhouden. Ik zet liever wat nuttigere checks bovenin een functie die echt wat te maken hebben met het proces/probleem/logica waar ik op dat moment mee bezig ben. In >80% van de gevallen dat ik een referentie gebruik naar een class wil ik nimmer of te nooit dat het een null pointer is. Ik hou er niet van om mezelf te herhalen en ik geloof er in dat iedere regel code die je minder kunt schrijven (zonder rare fratsen als for-loops in één regel) geld bespaart.
----------

Het is een significant deel van mijn werk omdat het in zeker de helft van mijn functies voorkomt. Het is bovendien foutgevoelig ook al doe je je checks netjes. Ik begrijp daarom ook niet waarom het niet in C#, wat daar de achterliggende technische reden van is.

[Voor 17% gewijzigd door BikkelZ op 18-06-2012 14:15]

iOS developer


  • MrBucket
  • Registratie: juli 2003
  • Laatst online: 27-05-2016
Niet-nullable reference types zijn niet mogelijk, want welke waarde zouden ze hebben voordat ze geinitialiseerd zijn? De enige oplossing is om zo'n variabele meteen te initialiseren zodra deze in scope komt, maar dan zit je nog met het probleem dat je in theorie in dezelfde scope 2 van zulke non-nullable variabelen kan declareren, die elk de ander gebruiken als argument voor hun constructor....

Volgens mij is TS op zoek naar een manier om invarianten af te dwingen in code zonder ze expliciet uit te hoeven programmeren. Je zou naar eens naar C# contracts kunnen kijken.

Betere link: http://msdn.microsoft.com/en-us/library/dd264808.aspx

[Voor 5% gewijzigd door MrBucket op 18-06-2012 14:18]


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

Zoals ik al zei; ik doe null checks eigenlijk voornamelijk (niet uitsluitend) daar waar er "surface area" is; waar user input de code in gaat, waar je api A aan api B knoopt, waar component X met Y communiceert. Het komt bij mij dan ook niet echt in de buurt van "de helft van mijn code". Je krijgt wel steeds meer van deze checks wanneer je met van die fijne API's werkt die "null" returnen i.p.v. een exception gooien voor zaken als
myconn = OpenDB(dsn, ...); e.d.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
Ik heb weer even voldoende leesvoer om me in te gaan verdiepen, waarvoor dank _/-\o_

Mocht ik nog vragen hebben meld ik me weer :)

@RobIII -> dan heb jij vaker dan ik de luxe dat je aan afgesloten delen waar niemand anders meer gaat lopen rommelen werkt. Een NullPointerException uit mijn code betekent dat ík een fout gemaakt heb, anders had namelijk je call afgevangen. Ik vind het een stuk zinniger om een ArgumentNullException te geven, dan weet de andere programmeur namelijk dat het niet zomaar een bug is.

[Voor 6% gewijzigd door BikkelZ op 18-06-2012 14:35]

iOS developer


  • epic007
  • Registratie: februari 2004
  • Laatst online: 26-11 15:23
BikkelZ schreef op maandag 18 juni 2012 @ 12:43:
..en wat er vervolgens mee te doen als het inderdaad null is.
Ik ben ook benieuwd wat je normaal doet als er toch null meegegeven wordt. Ga je de boel proberen te fixen (door bv een default date aan te maken o.i.d) of throw je een wat vriendelijkere exceptie?
Door proberen te fixen wordt je code alleen maar complexer lijkt me. Als je functie als preconditie heeft dat er geen null mag worden meegegeven en dit gebeurt toch dan zou er gewoon een exceptie gethrowd moeten worden.
Zo ben ik door schade en schande wijs geworden, door alles te checken komen bugs alleen maar op een later moment aan het licht.

  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

BikkelZ schreef op maandag 18 juni 2012 @ 14:34:
@RobIII -> dan heb jij vaker dan ik de luxe dat je aan afgesloten delen waar niemand anders meer gaat lopen rommelen werkt.
Nee, ik maak de afweging waar 't nuttig is een dergelijke check te doen en waar niet. In de internals van code ga ik echt niet op elke method boundary een null check doen. Als de ander zo nodig mijn (interne) method wil aanroepen met een null parameter dan is dat zijn/haar probleem. Daar kiest diegene dan voor en is dan ook zelf verantwoordelijk voor 't klappen of undefined behaviour van die code. Nogmaals: dat is toch niet anders als dat je een CreateCustomer(string name) hebt die vervolgens wordt aangeroepen als CreateCustomer("1234AB") waarbij je een postcode in "name" stopt? Daarmee treedt er geen exception op maar is de bedoeling van de functie alsnog niet overeenkomstig het gebruik ervan.
BikkelZ schreef op maandag 18 juni 2012 @ 14:34:
Een NullPointerException uit mijn code betekent dat ík een fout gemaakt heb, anders had namelijk je call afgevangen.
Again; op 'public' boundaries / surface area: ja: dat had je moeten vangen. In internals: nee. Dan zorgt je collega maar dat 'ie weet waar 'ie mee bezig is. Je moet gewoon accepteren dat je niet alles kunt (blijven) vangen. Ergens trek je de lijn. Ik doe dat op de "public boundaries". Alles beyond dat is voor eigen risico. Gebruik je 't verkeerd, of, "tegen de documentatie in", dan moet je niet mauwen als 't niet doet wat je graag wil dat 't doet. De manier die jij hanteert is inderdaad erg omslachtig en maakt van elke method op zichzelf al haast een applicatie.

[Voor 13% gewijzigd door RobIII op 18-06-2012 14:43]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
epic007 schreef op maandag 18 juni 2012 @ 14:35:
[...]

Ik ben ook benieuwd wat je normaal doet als er toch null meegegeven wordt. Ga je de boel proberen te fixen (door bv een default date aan te maken o.i.d) of throw je een wat vriendelijkere exceptie?
Door proberen te fixen wordt je code alleen maar complexer lijkt me. Als je functie als preconditie heeft dat er geen null mag worden meegegeven en dit gebeurt toch dan zou er gewoon een exceptie gethrowd moeten worden.
Zo ben ik door schade en schande wijs geworden, door alles te checken komen bugs alleen maar op een later moment aan het licht.
Ik throw zo veel en zo snel mogelijk Exceptions, aangezien dat makkelijker te testen is en duidelijk maakt dat een bepaald iets wat fout gaat niet veroorzaakt wordt doordat er een fout in de code zit. Stel je hebt een functie die een vraagteken zoekt in een string:

C#:
1
2
3
4
5
6
int FindQuestionMark(string searchString)
{
if (searchString == null) throw new ArgumentNullException();
if (searchString == string.Empty) return -1;
// search code
}


Je zou ook kunnen zeggen:
C#:
1
2
3
4
5
int FindQuestionMark(string searchString)
{
if (string.IsNullOrEmpty(searchString)) return -1;
// search code
}


Want tja, een null string daar zit toch geen vraagteken in?

Ik doe dat dus niet, want je hebt een string nodig om in te zoeken, en als die er niet is, kun je ook niet zeggen of er een vraagteken in zit.

iOS developer


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
RobIII schreef op maandag 18 juni 2012 @ 14:39:
Again; op 'public' boundaries / surface area: ja: dat had je moeten vangen. In internals: nee. Dan zorgt je collega maar dat 'ie weet waar 'ie mee bezig is. Je moet gewoon accepteren dat je niet alles kunt (blijven) vangen. Ergens trek je de lijn. Ik doe dat op de "public boundaries". Alles beyond dat is voor eigen risico. Gebruik je 't verkeerd, of, "tegen de documentatie in", dan moet je niet mauwen als 't niet doet wat je graag wil dat 't doet. De manier die jij hanteert is inderdaad erg omslachtig en maakt van elke method op zichzelf al haast een applicatie.
Nou als het om een klein stukje normaliseren gaat, bijvoorbeeld een stuk for each loop in een eigen functie zetten, dan denk ik "ok". Zeker private methods daar doe ik dat ook regelmatig gewoon niet bij. Maar als het groter wordt, bijvoorbeeld tussen classes en public functions dan vertrouw ik niemand meer, ook niet mezelf.

iOS developer


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

Even aangenomen dat de functie wat complexer is dan FindQuestionmark, er meer dan 1 parameter de functie in gepassed wordt en je de internals niet kent op voorhand:

1) "Mijn methode": https://compilify.net/1vg/1
NullReferenceException: Object reference not set to an instance of an object.
Er is ergens iets null dat geen null had moeten zijn.

2) "Jouw methode": https://compilify.net/1vg/2
ArgumentNullException: Value cannot be null.
De exception vertelt je nu dat er "een parameter" null was die dat niet mocht zijn.

In beide gevallen krijg je een exception wanneer searchString null is. What's the difference (op 't type exception na)?

Gebruik dan op z'n minst de constructor waarin je de parameter specificeert:
3) https://compilify.net/1vg/3
ArgumentNullException: Value cannot be null. Parameter name: searchString

"Mijn methode" (1), nogmaals, gebruik ik enkel in internals. Op public interfaces (wat je onder public verstaat is wel wat context afhankelijk) doe ik wél null-checks op de 3e manier. Voor internals ga ik voor methode 1.

Alle drie de methodes returnen gewoon -1 voor een lege string; het nut van die extra check (searchString == string.Empty) in methode 2 zie ik dus ook niet.

[Voor 20% gewijzigd door RobIII op 18-06-2012 15:11]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 18:05

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

RobIII schreef op maandag 18 juni 2012 @ 13:31:
[...]

Een DateTime/bool zijn niet nullable; een DateTime? en bool? wel. Ik begrijp dan ook niet goed wat je met "tegenhanger" bedoelt. Ze zijn pas nullable als je dat expliciet aangeeft.
Exactly his point. Bij value types zijn ze alleen nullable als je dat expliciet aangeeft. Waarom bij reference types niet?

Al jouw voorgestelde workarounds (unit tests e.d.) werken runtime. Liever pak je die fouten op tijdens compile time. Een compiler kan prima zien wanneer jij null of een nullable type convert naar een niet-nullable type. Dit werkt dan ook alleen met expliciete checks / casts.

Nice, een extensie voor Java, ondersteunde dit overigens jaren geleden al.

Wat ik overigens vooral frappant vind van deze topic is dat de status quo van .Net krampachtig lijkt te worden verdedigd. :)
MrBucket schreef op maandag 18 juni 2012 @ 14:16:
Niet-nullable reference types zijn niet mogelijk, want welke waarde zouden ze hebben voordat ze geinitialiseerd zijn?
Onzin-argument. Op dezelfde manier zou je kunnen redeneren dat references in C++ niet mogelijk zijn. Het simpele antwoord is: je bent ze verplicht altijd meteen te initialiseren.

[Voor 23% gewijzigd door .oisyn op 18-06-2012 15:41]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

.oisyn schreef op maandag 18 juni 2012 @ 15:34:
Nice, een extensie voor Java, ondersteunde dit overigens jaren geleden al.
Spec#, pas 3 keer genoemd in dit topic, ondersteunt dat ook.

Overigens, ook kun je in bepaalde gevallen een struct overwegen.

[Voor 75% gewijzigd door RobIII op 18-06-2012 15:43]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • BikkelZ
  • Registratie: januari 2000
  • Laatst online: 25-11 18:58
Ik ga met Spec# aan de slag, ik laat nog wel weten hoe het beviel.
Maar ik zie nog steeds de reden niet dat het niet gewoon in C# zou kunnen zitten. Want het enige wat je moet afdwingen is dat een pointer altijd meteen met een waarde geïnitialiseerd moet worden, dat lijkt me niet zo heel moeilijk :?
RobIII schreef op maandag 18 juni 2012 @ 15:05:
Even aangenomen dat de functie wat complexer is dan FindQuestionmark, er meer dan 1 parameter de functie in gepassed wordt en je de internals niet kent op voorhand:

1) "Mijn methode": https://compilify.net/1vg/1
NullReferenceException: Object reference not set to an instance of an object.
Er is ergens iets null dat geen null had moeten zijn.

2) "Jouw methode": https://compilify.net/1vg/2
ArgumentNullException: Value cannot be null.
De exception vertelt je nu dat er "een parameter" null was die dat niet mocht zijn.

In beide gevallen krijg je een exception wanneer searchString null is. What's the difference (op 't type exception na)?

Gebruik dan op z'n minst de constructor waarin je de parameter specificeert:
3) https://compilify.net/1vg/3
ArgumentNullException: Value cannot be null. Parameter name: searchString

"Mijn methode" (1), nogmaals, gebruik ik enkel in internals. Op public interfaces (wat je onder public verstaat is wel wat context afhankelijk) doe ik wél null-checks op de 3e manier. Voor internals ga ik voor methode 1.

Alle drie de methodes returnen gewoon -1 voor een lege string; het nut van die extra check (searchString == string.Empty) in methode 2 zie ik dus ook niet.
Het was een snel stukje voorbeeldcode waar ik met name demonstreerde dat ik geen -1 retourneerde in het geval van een null-string. Er zitten ook geen tabs in bijvoorbeeld. Het is ook natuurlijk dermate simpel dat je er normaal niet eens een functie voor zou schrijven.

Maar stél nou dat ik een functie heb met een loopje en daarin zitten een paar checks en nog wat dingen, die wil ik dan normaliseren. Dus komt er in mijn class een extra private functie bij, en wordt er in die loop een functie call gedaan. Dan ga ik ook niet meer checken.

[Voor 7% gewijzigd door BikkelZ op 18-06-2012 15:39]

iOS developer


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 18:05

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

RobIII schreef op maandag 18 juni 2012 @ 15:37:
[...]


Spec#, pas 3 keer genoemd in dit topic, ondersteunt dat ook.
I know, mijn punt ging over "jaren geleden". Het is niet nieuw, maar vooral jij leek de feature af te doen als onzinnig. Edoch is er al best lang vraag naar.

Het nu in C# bouwen wordt natuurlijk lastig, dan is alle code in een klap incompatble, of het is niet consistent (? by default voor ref types en ! by default voor value types). Nullables zaten ook niet in C# als ik me niet vergis.

[Voor 30% gewijzigd door .oisyn op 18-06-2012 15:47]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • RobIII
  • Registratie: december 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

.oisyn schreef op maandag 18 juni 2012 @ 15:43:
[...]

I know, mijn punt ging over "jaren geleden". Het is niet nieuw, maar vooral jij leek de feature af te doen als onzinnig.
Spec# stamt ook al uit 2004 ofzo; en Code Contracts (waarmee dit ook mogelijk is (afaik althans)) zitten in .Net 4.0.
Ik doe 't daarbij niet af als onzinnig maar wel als iets waar ik prima mee kan leven en het accepteer zoals 't is. Ik heb ook de suggestie gedaan een ticket bij MS aan te maken als TS daar behoefte aan heeft. Ik heb die behoefte niet, maar kan wel begrijpen dat die behoefte er is.

Ook Jon Skeet's artikeltje is overigens 't lezen waard; maar dat is ook runtime.

[Voor 14% gewijzigd door RobIII op 18-06-2012 15:52]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 18:05

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

Dat is prima, maar daar is niet waar de topic voor geopend werd natuurlijk en daarmee een beetje een dooddoener :)

De TS:
Zitten daar praktische nadelen aan? Is het lastig te implementeren? Ik kan me gewoon niet voorstellen dat we het niet hebben.
Ik kan me geen praktische nadelen bedenken, en lastig te implementeren lijkt het me zeker niet.

[Voor 23% gewijzigd door .oisyn op 18-06-2012 15:49]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • Hydra
  • Registratie: september 2000
  • Laatst online: 18:26
RobIII schreef op maandag 18 juni 2012 @ 14:39:
Again; op 'public' boundaries / surface area: ja: dat had je moeten vangen.
IMHO alleen op plekken waar het anders echt een probleem op zou leveren (omdat je geen null in een database wil stoppen en geen 'null' in een stuk tekst wil hebben) maar in alle andere gevallen is het prima als er gewoon 'vanzelf' een NPE gegooid wordt.

Tel je hebt deze methode:
code:
1
2
3
4
    public void doSomething(Object myObject)
    {
        doSomethingElse(myObject.toString());
    }


Dan is het absoluut niet nodig om eerst te checken of myObject niet null is, ook als dit een 'publieke' methode is die extern / door anderen gebruikt wordt.
BikkelZ schreef op maandag 18 juni 2012 @ 15:37:
Ik ga met Spec# aan de slag, ik laat nog wel weten hoe het beviel.
Maar ik zie nog steeds de reden niet dat het niet gewoon in C# zou kunnen zitten.
Kan prima. Zorg dat je genoeg mensen bij mekaar krijgt die het een issue vinden en je zou het zomaar eens voor elkaar kunnen krijgen. Punt is dat het gewoon nogal een nonissue is. Zo vaak hoef je het helemaal niet te checken.

[Voor 25% gewijzigd door Hydra op 18-06-2012 16:49]

https://niels.nu


  • sonix666
  • Registratie: maart 2000
  • Laatst online: 22-11 18:08
.oisyn schreef op maandag 18 juni 2012 @ 15:34:
[...]

Onzin-argument. Op dezelfde manier zou je kunnen redeneren dat references in C++ niet mogelijk zijn. Het simpele antwoord is: je bent ze verplicht altijd meteen te initialiseren.
Ook in C++ kun je met gemak nullable references krijgen.

code:
1
int &nullRef = *((int *)NULL);


Alleen als je dat doet, dan ben je gewoon ongelooflijk stom bezig. ;)

  • .oisyn
  • Registratie: september 2000
  • Laatst online: 18:05

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

That wasn't really the point now was it :). Het punt was dat je in C++ een reference verplicht bent te initialiseren. Dat kan in C# ook best:
C#:
1
2
object! o; // error, o moet je initialiseren
object! o = new object(); // ok

Hetzelfde gaat overigens op voor readonly variabelen. Die moet je ook initialiseren.

Overigens is jouw code undefined behaviour, dus nee, het kan in principe niet.

[Voor 11% gewijzigd door .oisyn op 19-06-2012 00:25]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.

Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee