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.