Oprettet ons. d. 19. oktober 2011 kl. 14:32:21

lasserasch
lasserasch (10.207 point. Point ude: 480)
www.r-coding.dk

smart måde at håndtere null exceptions på.

Hejsa.

Jeg opstiller lige et lille eksempel her:

Jeg har følgende objekter:

1. Customer
2. Order
3. Orderdata
4. Product

Customer objektet har en instans af et Order object, og Order objektet har en instans af Product objektet.

På den måde kan man altså sige :

Customer c = new Customer("brugernavn", "password");
Double productprice = c.Order.Orderdata.Product.Price;


Jeg ved godt at eksemplet ikke helt er realistisk, men det er ikke så vigtigt i denne sammenhæng.

Faktum er at min kode kan fejle hvis blot en af de instanser som jeg skal igennem for at hente prisen på produktet er null.

Det håndtere jeg med en masse if { } sætninger i min kode idag.

Altså sådan her :

Double productprice;
Customer c = new Customer("brugernavn", "password");
if (c != null)
{
if (c.Order != null)
{
if (c.Order.OrderData != null)
{
if (c.Order.Orderdata.Product != null)
{
productprice = c.Order.Orderdata.Product.Price;
}
}
}
}

Jeg ved godt det kunne stilles lidt smartere op, men stadigvæk er jeg nødt til at tjekke alle instanser for at se om de er null.

Findes der ikke en eller andet smart måde at tjekke om den værdi jeg vil have fat i (price) kan hentes eller ej. Jeg er ikke så interesseret i at vide præcist om det var product eller Orderdata som var null.

Jeg vil bare gerne vide om jeg kan finde værdien eller ikke.

Og Try/Catch er ikke en option.... :-)

Håber en har lidt input og måske et guldkorn jeg ikke kendte.

Skrevet ons. d. 19. oktober 2011 kl. 14:38:36| #1

kalp
kalp (244.223 point)
hvorfor laver du ikke en property i Customer der returnere true eller false? og din logik er deri.

Customer c = new Customer("brugernavn", "password");
if (c != null c.IsValid){

}

sådan ca.

Skrevet ons. d. 19. oktober 2011 kl. 14:40:10| #2

kalp
kalp (244.223 point)
Der mangler lige && :)

men min pointe er, at du kan flytte alle de tjeks til at være en del af Customer og dermed slippe for at skulle gentage dine tjek overalt.

Skrevet ons. d. 19. oktober 2011 kl. 15:06:09| #3

buzzzz
buzzzz (48.826 point)
ifyoudo.net
Du bryder i hvert fald et design pattern jeg ikke lige kan huske hvad hedder.

Du bør, i min verden have en Method som tager sig af ordre og kigger på den og tjekker for null.

Der derefter OrdreData, Product ... og ja, stop der da en Price nok er en value type og dermed ikke null.

Dermed er der ikke så mange tjek der skal laves igen og igen, da der ligger i din logik.

Skrevet ons. d. 19. oktober 2011 kl. 15:07:46| #4

softspot
softspot (101.915 point)
www.softspot.dk
Kan du ikke lave "on demand"-oprettelse på objeterne via properties, således du aldrig behøver tænke på om objektet eksisterer eller ej. Objektet oprettet "on demand" kunne så blot indeholde default-data og evt. reference behøver i princippet ikke blive gemt i det indeholdende objekt, men blot returneret og glemt af det oprettende objekt. Noget i stil med:

class Customer
{
  private Order _order;

  public Order Order {
    get {
      if(_order == null)
        return new Order();

      return _order;
    }
  }
}

Hvis du så ville implementere lazy-loading på et senere tidspunkt kunne du ændre koden til noget á la:

class Customer
{
  private Order _order;
  private int _orderid;

  public Order Order {
    get {
      if(_order == null && _orderid == 0)
        return new Order();

      if(_order == null) {
        _order = new Order();
        _order.Load(_orderid);
      }

      return _order;
    }
  }
}

Jeg har undladt andre egenskaber og evt. metoder i koden - du kan nok se idéen.

Skrevet ons. d. 19. oktober 2011 kl. 15:14:24| #5


Skrevet ons. d. 19. oktober 2011 kl. 16:01:06| #6

arne_v
arne_v (1.016.169 point)
For det foerste kan du pynte koden lidt ved at udnytte at && er en short circuit operator, saa:

Double productprice;
Customer c = new Customer("brugernavn", "password");
if (c != null && c.Order != null && c.Order.OrderData != null && c.Order.Orderdata.Product != null)
{
productprice = c.Order.Orderdata.Product.Price;
}

For det andet er der nogle OO overvejelser omkring designet.

A) Burde der i virkeligheden vaere en business metode i Customer der skulle kaldes i.s.f. bare at hente en property og opererer paa den?

B) Burde man nogensinde kunne komme i den situation hvor man vil hente prisen for noget som ikke er sat korrekt op endnu? Og hvis ikke er NullReferenceException saa ikke en glimrende maade at meddele at her har programmoeren kvajet sig?

Skrevet ons. d. 19. oktober 2011 kl. 20:45:12| #7

tolamaps
tolamaps (2.000 point)
Det tjek der er på (c != null) kan i øvrigt udelades da den aldrig vil være null i den viste kodestump (enten får du instantieret dit objekt, eller også kaster den en exception).

Skrevet tor. d. 20. oktober 2011 kl. 09:05:40| #8

janus_007
janus_007 (30.915 point)
Hvorfor kan du ikke arbejde med try-catch?

Skrevet søn. d. 27. november 2011 kl. 01:36:23| #9


Skriv et indlæg




Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] [img]link til billede[/img]
Web- og emailadresser omdannes automatisk til links

Log ind

   

   

Seneste spørgsmål

Print fra Windows Service på Win2008

Oprettet den 24. maj 2012 kl. 11.17
jps6kb giver 200 point for svar | Giv et svar »

Udskrive en Breadcrumb (Jeg er her >>)

Oprettet den 18. maj 2012 kl. 12.04
Qbruger giver 200 point for svar | Giv et svar »

Hjælp til at lokalisere fejl i CMS (synkron.via) dll

Oprettet den 16. maj 2012 kl. 19.31
jokkejensen giver 200 point for svar | Giv et svar »



   




Tips & Tricks fra PC World

Teaser billede

Læserne: Her er vores værste it-indkøb

Det er ikke al it-udstyr, som er det rene guld. Her er nogle af læsernes skrækhistorier.


Anmeldelser fra PC World

Teaser billede

Test: Mobil med Ferrari-design - og en Trabant-motor

Motorola har begået endnu en smartphone med lækkert design og potentiale til at være blandt de bedste. Men den når ikke i mål. Se her hvorfor.


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Sådan siger du farvel til Facebook

Læs her, hvordan du dropper Facebook og i stedet anvender nogle brugervenlige alternativer, så du stadig kan være social på nettet.


Nyheder fra Computerworld

Teaser billede

Galleri: De fedeste håndholdte gennem 40 år

Her har du de mest banebrydende håndholdte computere gennem alle tider.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger