Fit and finish for your data structures / DTO’s

This issue came up the other day at work. When I am working on a project and if I have data structures, DTO’s, or “classes that hold stuff”, there are some things I try to do to tighten the code up:

Argument validation:
First, I might argue that argument validation should not ever be an afterthought, it should be part of your regular coding. However, there are times when you are just “trying to get something to work, first” and you might skip it. So for me, what I do as part of my final sweep through the code, I go through each class and make sure every method has proper argument validation.

Argument validation is very simple, but an incredibly important part of coding – yet it’s probably the most overlooked aspect. Argument validation is simply the notion of validating that the arguments that were passed in, are valid and usable by your method. For example, check for:

  • String.IsNullOrEmpty(argument) – you might want to throw an ArgumentException
  • Make sure reference types are not null – you should throw an ArgumentNullException
  • Make sure numbers are within valid ranges – you should throw an ArgumentOutOfRangeException

Here is a short example:

/// <summary>

/// Returns a formatted customer name.

/// </summary>

/// <exception cref=”ArgumentException”>If <param name=”lineBreaker”/>

/// is null or empty.</exception>

/// <exception cref=”ArgumentNullException”>If <param name=”customer”/>

/// is null.</exception>

public string GetFormattedCustomerName(Customer customer, string lineBreaker)

{

    if (customer == null)

        throw new ArgumentNullException(

             “Argument ‘customer’ cannot be null.”);

 

    if (string.IsNullOrEmpty(lineBreaker))

        throw new ArgumentException(

              “Argument ‘lineBreaker’ cannot be null or empty.”);

 

    // Start my regular code here.

Note that not only did I validate the arguments, but I (what I call) “publish the exceptions” as well with XML code comments (the “<exception…” statements). What does that do? Well in C#, it shows you what exceptions this method can throw:

image

It will also publish those possible exceptions in Sandcastle document with the “reason” I specified in between the opening and closing tags. So again, this to me is part of proper “fit and finish” of your code – not only to make sure you have proper argument validation everywhere, but to publish those exceptions with a decent amount of XML code comments.

XML Code Comments:
I’ve spoken about XML code comments many times, and continue to be a big fan. They help document your code, they give meaningful intellisense to the developer consuming your code (including even just you), and it also is a way to generate MSDN-style, professional-quality component documentation. Google on bing for Sandcastle, “sandcastle help file builder” for me – or search on this blog, as I’ve done a few posts on the details.

.Equals, .ToString, ==, and !=:
If you have your own data structure, then you really should define how it interacts with other objects. Below is an example where I have a class that has a Guid-based “Id”, and a string-based “Name”. With that, I have this code:

/// <summary>

/// Returns a <see cref=”String”/> that represents

/// the current <see cref=”Object”/>.

/// </summary>

public override string ToString()

{

    string temporaryId = new Guid().ToString();

    string temporaryName = “(Not Set)”;

 

    if (Name == null)

        temporaryName = “(Null)”;

    else if (Name == string.Empty)

        temporaryName = “(Empty)”;

    else

        temporaryName = Name;

 

    if (Id != null)

        temporaryId = Id.ToString();

 

    return string.Format(“{0} ({1})”,

        temporaryName, temporaryId);

}

 

/// <summary>

/// Determines whether the specified System.Object

/// is equal to the current System.Object.

/// </summary>

/// <param name=”obj”>The System.Object to compare

/// with the current System.Object.</param>

/// <returns>True if the specified System.Object is

/// equal to the current System.Object; otherwise, false.</returns>

public override bool Equals(object obj)

{

    if (obj == null || GetType() != obj.GetType())

        return false;

 

    IIdentifiable currentItem = (IIdentifiable)obj;

 

    return (currentItem.Id.Equals(Id));

}

 

/// <summary>

/// Serves as a hash function for a particular type.

/// </summary>

public override int GetHashCode()

{

    return Id.GetHashCode() + Name.GetHashCode();

}

 

/// <summary>

/// Equal (==) operator overload.

/// </summary>

/// <param name=”a”>The first object to compare.</param>

/// <param name=”b”>The second object to compare.</param>

/// <returns>True if the two items are equal;

/// otherwise false.</returns>

public static bool operator ==(ControllableBase a, ControllableBase b)

{

    if (a == null || b == null)

        return false;

 

    return a.Id == b.Id;

}

 

/// <summary>

/// Not-Equal (!=) operator overload.

/// </summary>

/// <param name=”a”>The first object to compare.</param>

/// <param name=”b”>The second object to compare.</param>

/// <returns>True if the two items are not equal;

/// otherwise false.</returns>

public static bool operator !=(ControllableBase a, ControllableBase b)

{

    if (a == null || b == null)

        return true;

 

    return a.Id != b.Id;

}

As you can see, I add appropriate logic for how .ToString(), .Equals, ==, and != work. Note too that despite the examples in MSDN, I actually have proper argument validation here. If the object you pass in is null, then it’s not equal. If the type you pass in is not of the right type, it’s not equal. If you pass those two checks, then I actually check for a comparison.

This sort of functionality should really be added to any custom data structures you make, to make sure IEquatable and IComparer, and just regular == and != work correctly with your object.

Tagged with: , , , , , ,
Posted in .NET 3.5, .NET 4.0, ASP.NET, ASP.NET MVC, Best-practices, Organization will set you free, Professional Development, Security, Uncategorized, WCF, WPF and MVVM
2 comments on “Fit and finish for your data structures / DTO’s
  1. Kuba says:

    I think your approach to != operator implementation is wrong. You should depend on == operator (return !(a==b)) because if you’ll add something to your class you must change == code and != as well.

    Like

  2. Rob Seder says:

    Kuba – great point, I think I agree!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 2 other followers

%d bloggers like this: