In your applications there may be times when you want to give the user the ability to override a setting or configuration value.  Often times you want to provide sensible defaults so that every single configuration option does not have to be specified, only those you which to override.  I want to show a very simple way to make your applications a bit smarter when creating classes with overridable default values.

Example 1:

   1: public class DemoObejct
   2: {
   3:     private string DEFAULT_MESSAGE = "Thank you for your order";
   4:     
   5:     private string message = DEFAULT_MESSAGE;
   6:     
   7:     public string Message
   8:     {
   9:         get { return message; }
  10:         set { message = value; }
  11:     }
  12: }

Example 2:

   1: public class DemoObejct
   2: {
   3:     private string DEFAULT_MESSAGE = "Thank you for your order";
   4:     
   5:     private string message;
   6:     
   7:     public string Message
   8:     {
   9:         get { return message ?? DEFAULT_MESSAGE; }
  10:         set { message = value; }
  11:     }
  12: }

So what's the difference?  The difference IS subtle but I consider the following code snippet:

   1: var obj = new DemoObject();
   2:  
   3: Console.WriteLine(obj.Message);
   4:  
   5: obj.Message = null;
   6:  
   7: Console.WriteLine(obj.Message);

Setting the Message property to null in line 5 results in different behavior between the two examples.  I find the second example to be preferable, setting the property to null invokes the default message again.  It's a very simple thing you can do to provide a more robust object

Here are two more examples where I use this strategy often:

Integers and Default Values:

   1: public class DemoObject
   2: {
   3:     private int? attemptThreshold;
   4:     private const int DEFAULT_ATTEMPTTHRESHOLD = 3;        
   5:         
   6:     public int AttemptThreshold
   7:     {
   8:         get { return attemptThreshold.HasValue ? attemptThreshold.Value : DEFAULT_ATTEMPTTHRESHOLD; }
   9:         set { attemptThreshold = value; }
  10:     }
  11: }

Logging Component:

   1: public class DemoObject
   2: {
   3:     private ILogger logger;
   4:  
   5:     public ILogger Logger
   6:     {
   7:         get { return logger ?? NullLogger.Instance; }
   8:         set { logger = value; }
   9:     }
  10: }

The above logging example is where this type of strategy really shines.  It prevents NullReferenceExceptions in your code if by chance your logger gets a null value at some point, again providing for a more robust object and application.


 
Comments are closed.