tags:

views:

67

answers:

2

I'm reading some data from an XML format and putting it in my classes and am just wondering what the best practice is regarding fields that can be empty and, if they are empty, have a default value. Values that haven't been supplied don't need to be written back to the file.

I was thinking of using nullable types, however, what's the best way in code of specifying a default value (though I wouldn't need a default value for every field as not all fields have a specified default value or the default value is 0)

At the moment I'm using this:

class SomeElement
{
    public const int DefaultFoo = 123;

    public int? Foo { get; set; }
}

but don't know if the following would be more obvious:

class SomeElement
{
    // Setting HasFoo to false will set Foo to the default value
    public bool HasFoo { get; set; }
    // Setting Foo to anything will set HasFoo to true
    public int Foo { get; set; }
}

As some of the classes have lots of properties, the second option will create lots more methods in the classes, however, might be easier to use if you don't care whether Foo has a value or not.

The final alternative might be using either a static method in the base class or an extension method to make the default easier to get (idea based on this)

// In some method using the class
int value = SomeElementBase.GetValueOrDefault(() => myObj.Foo);
// or an extension method
int value = myObj.GetValueOrDefault(x => x.Foo);

I'd still supply the DefaultFoo fields but the static/extension method might make it easier to access?

What are your thoughts? Has anybody come across this problem before? Should I just use default values and when saving back to the file omit fields that equal their default value?

+8  A: 

I think a nullable field is preferable. No superfluous code keeping them in synch in your file, the intent is very clear, and you can just access Foo.HasValue which to my mind expresses your intent better than a separate HasValue property on the class.

kekekela
I also like more the version with the nullables. If another user examines the class only lazy, then he will eventually read wrong values, because he accesses the value-property without checking the state.
HCL
I agree. By using a `Nullable` the definition is tightly contained and you immediately know that it could be null. If you do two methods the distance between understanding is increased which leads to confusion.
Jerod Houghtelling
You make a good point about confusion, thanks. What about default values? Is the const field the best way to go? I guess in code you could have: myObj.Foo ?? SomeElement.DefaultFoo
Sam
+2  A: 

I would use a combination of nullables for values that don't have a default value, and overriding the default getter for values that do have a default value (assuming that you don't actually need to know whether or not the value you're getting is the default or not):

class SomeElement {
   public int? NoDefault {
      get; set;
   }

   private int? m_hasDefault;
   public int? HasDefault {
      set { m_hasDefault = value; }
      get {
         if(m_hasDefault.HasValue)
            return m_hasDefault;
         else
            return WhateverTheDefaultShouldBe;
      }
   }
}

Still returning nullables in both cases to keep things consistent, and to hide any differences between properties that have default values and those that don't to the calling code (this way you could easily change which values have defaults or not in the class without affecting the code that uses the class).

Rudism