I have been trying to figure out the best way to handle default values. Setting a ID value to 0 makes sense, but if it is a money value or other that is not initially set, when you encounter it later in your code, it is impossible to tell if it has been set or was set to 0. If a money value is set to null, then you know it has not been set. Additionally, when dealing with the database, it is simple to know if you need to write a null value to a field vs trying to figure out if it is supposed to be null or not.
What is the accepted way to handle this?
Class MyModel
{
public int Id {get;set;}
public string Title {get;set;}
public DateTime CreatedDate {get;set;}
public bool IsActive {get;set;}
//CLR will automatically set these values
Public MyModel()
{
Id = 0;
Title = String.Empty;
CreatedDate = "1/1/0001";
IsActive = false;
}
}
vs
Class MyModel
{
public int? Id {get;set;}
public string Title {get;set;}
public DateTime? CreatedDate {get;set;}
public bool? IsActive {get;set;}
//CLR will automatically set these values
Public MyModel()
{
Id = null;
Title = null;
CreatedDate = null;
IsActive = null;
}
}
You can always mix approaches, depending on your domain.
static class ID
{
public const int Unassigned = -1;
}
class MyModel
{
public int Id { get; private set; }
public string Title { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsActive { get; set; }
public bool? IsAwesome { get; set; }
Model ()
{
// you may use "default" constants...
Id = ID.Unassigned;
}
// you may use optional parameters or overloads
public MyModel (string title,
DateTime created = DateTime.Now, // default values may be concrete
bool? isAwesome = null) // or nullable as well
: this () // and you can chain-call constructors!
{
Title = title ?? "<no title>"; // you don't always want null to come through
CreatedDate = created;
IsAwesome = isAwesome;
}
}
// Possible usages:
var model = new MyModel ("Hello", new DateTime (2001, 1, 1));
var model = new MyModel ("world", isAwesome: true);
var model = new MyModel (null) {
IsActive = true
};
It may make sense for some attributes to have null
values, as in “not set”.
In your example, perhaps a model really doesn't have an Id
before it is persisted to the database. If this is the case, and an id-less model makes sense in terms of business logic, a nullable Id
is better than Id = 0
. However, if your application never works with id-less models, and usually expects Id
to equal something, it would be crazy to write
if (model.Id != null)
each time you want to do something with it.
In this case, you should probably go with Id = 0
by default.
You could also introduce a constant (as I've done above) though I wouldn't recommend it for anything but ids, and only in case they are heavily used by code elsewhere.
Again, everything depends on the domain.
Your job is to ensure that objects violating business rules can't be created easily.
What is the accepted way to handle this?
Accepted? It depends on the domain.
If a money value is set to null, then you know it has not been set.
Not necessarily. Imagine I'm using a banking application, and I want to search for a particular transaction, and I get a dialog that looks like this:
Enter the fields you know:
Transaction date: 6/26/2011
Payee: Apple
Amount:
Now TransactionSearchParameters.Amount
should be set to null. You can't distinguish this from it not being set.
Additionally, when dealing with the database, it is simple to know if you need to write a null value to a field vs trying to figure out if it is supposed to be null or not.
You should spend more time modeling your domain properly, and then let an ORM figure out how to get that stuff into the database properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With