Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have an application which is made up of many different control types, each of which can, optionally, be linked with a parameter object.

These are then saved in an XML file for reloading later. To link the control to the parameter, where specified, the control stores the parameters ID. This is then searched for during loading and re-linked.

However as this is optional, if the parameter is not specified I get a NullReferenceException when trying to access the ID which is understandable. I could resolve this by putting a check around the line in question. However i would have to do this for many different control types and more than just one reference as show in this basic example.

So my question is, is there an elegant way to somehow allow this call to just return an empty string instead of this exception?

public class Parameter
{
  public string ID;
}

public class LabelCtrl
{
  public string Name;
  public Parameter LinkedParameter;
}

public class XMLManager
{
  public void SaveControl(ControlInstance_LabelCtrl ci)
  {
    xmlWriter.WriteStartElement("ControlInstance_LabelCtrl");
    {
      xmlWriter.WriteElementString("Name", ci.Name);
      // Elegant way to insert empty string instead of causing NullReferenceException error
      xmlWriter.WriteElementString("LinkedParameter", ci.LinkedParameter.ID);
    }
    xmlWriter.WriteEndElement();
  }
}
share|improve this question
    
Why not use Try/Catch? Or am I missing something? – uteist Jun 14 at 9:15
    
Why catch Exceptions if you can prevent them? @uteist – Patrick Hofman Jun 14 at 9:17
    
I mean, just put it in try/catch and if it's catched, return String.Empty. Or an If x is null then do something block. I still wonder if I'm missing something @PatrickHofman – uteist Jun 14 at 9:29
    
Yes, exception handling is expensive. If you can prevent an exception from happening, you should do that. Exceptions are for exceptions, not for your program flow. @uteist – Patrick Hofman Jun 14 at 9:32
    
I think this would really bloat the code as it would need to be kept in line, to ensure the continuity of the XML file. and would be in many places as it is acceptable to have these are null. – TheGrovesy Jun 14 at 9:33
up vote 2 down vote accepted

Use the null propagation operator (available from C# 6):

xmlWriter.WriteElementString("Name", ci.Name);
xmlWriter.WriteElementString("LinkedParameter", ci.LinkedParameter?.ID);

Or for pre-C# 6 use:

ci.LinkedParameter != null ? ci.LinkedParameter.ID : null;
share|improve this answer
    
Okay, you are right. – Patrick Hofman Jun 14 at 9:16
    
@PartickHofman I didn't know about this and looks perfect... unfortunatly I am using C#4.5 and cannot upgrade at the moment! :( – TheGrovesy Jun 14 at 9:35
    
Then use this: ci.LinkedParameter != null ? ci.LinkedParameter.ID : null;. – Patrick Hofman Jun 14 at 9:35
    
I had just come to this conclusion myself :) Many thanks for your help, and everyone elses input. – TheGrovesy Jun 14 at 9:40
    
Correct. An edit of OP which I didn't check too well... @HenkHolterman – Patrick Hofman Jun 14 at 15:30

Use a simple test against ci.LinkedParameter.ID as String:

if (!String.IsNullOrEmpty(ci.LinkedParameter.ID)) {
    xmlWriter.WriteElementString("LinkedParameter", ci.LinkedParameter.ID);
}
else {
    xmlWriter.WriteElementString("LinkedParameter", String.Empty);
}

or use simple try-catch block:

try {
    xmlWriter.WriteElementString("LinkedParameter", ci.LinkedParameter.ID);
} 
catch (e) {
    xmlWriter.WriteElementString("LinkedParameter", String.Empty);
}

Those statements apply if you don't want to change behavior of the model, CMIIW.

share|improve this answer
    
It's LinkedParameter that is null, not the ID - which wouldn't cause a NullReferenceException anyway.. – stuartd Jun 14 at 9:22

You could use a ternary operator if you don't use C# 6:

xmlWriter.WriteElementString("LinkedParameter", (ci.LinkedParameter != null) ? ci.LinkedParameter.ID : "");

It's an if/else but more compact and more elegant if you have lots of lines like this.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.