Avatar billede lasserasch Juniormester
19. oktober 2011 - 14:32 Der er 9 kommentarer

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.
Avatar billede kalp Novice
19. oktober 2011 - 14:38 #1
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.
Avatar billede kalp Novice
19. oktober 2011 - 14:40 #2
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.
Avatar billede Syska Mester
19. oktober 2011 - 15:06 #3
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.
Avatar billede softspot Forsker
19. oktober 2011 - 15:07 #4
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.
Avatar billede Syska Mester
19. oktober 2011 - 15:14 #5
Avatar billede arne_v Ekspert
19. oktober 2011 - 16:01 #6
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?
Avatar billede Slettet bruger
19. oktober 2011 - 20:45 #7
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).
Avatar billede janus_007 Nybegynder
20. oktober 2011 - 09:05 #8
Hvorfor kan du ikke arbejde med try-catch?
Avatar billede arne_v Ekspert
27. november 2011 - 01:36 #9
lasse??
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester