Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I make my object properties nullable or use the CLR default values for each type?

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;
    }
}
like image 904
jpshook Avatar asked Jun 27 '11 17:06

jpshook


Video Answer


2 Answers

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.

like image 138
Dan Abramov Avatar answered Oct 12 '22 23:10

Dan Abramov


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.

like image 42
jason Avatar answered Oct 13 '22 00:10

jason