tags:

views:

148

answers:

4

Lets say I have a Phone number my classes need to validate and keep track of and for the most part a phone number is just a string so in an attempt to be DRY one would just create a Phone class and inherit from string. Since I can't do that what is the next best approach? Adding a string as a private member and overloading the equal/= operators so it can be passed and set as a string?

+6  A: 

prefer composition over inheritance.

Do you want your phone number to be assignable from string? Certainly not because the following would be possible then:

Person.PhoneNumber = "FOO"

Something like this feels more natural:

Person.PhoneNumber = new PhoneNumber("015-123456");

You can do custom validation in the constructor and additionaly decide you want it to be immutable (ok, string would be immutable too)

Johannes Rudolph
My understanding is that taking Person.PhoneNumber = "FOO" and throwing an exception is a better practice then Person.PhoneNumber = new PhoneNumber("FOO"); throwing an exception for a constructor. But this may just be my C++ background ringing bells.
Aaron Fischer
Your ringing bells are generally correct, but we work in a GC environment here, so unsuccessful object creation is no problem. You could also make the Person.PhoneNumber constructor private and provide a static PhoneNumber.Parse method that is responsible for creating a PhoneNumber instance and validating the string.
Johannes Rudolph
+1  A: 

I would create PhoneNumber class with a private string member as you suggested. You can override the ToString() method if you wanted to provide consistent formatting (e.g. (123) 123-1234 or whatever), you could add some validation on a set method or a constructor to make sure the phone number had 10 digits (if a North American number).

Creating a PhoneNumber class allows you to extend the class later on if you need to. For example, you could enhance your phone number validation to check for invalid area codes and raise an error if the area code doesn't exist.

TLiebe
A: 

In short, yes, have a private member. However instead of overloading assignment I would suggest having a static parse member.

PhoneNumber p = PhoneNumber.Parse("704 - 576- 4000");

This is more standard, and more readable. Also even if you could inherit from string, I'd advise against it, as String has complex internal functionality that should be separate from your class. Also inheriting from string would expose a number of methods that wouldn't make sense for a phone number (ie: Concat, inaccurate compares, etc).

C. Ross
A: 

May I suggest that you take Johannes Rudolph's or C. Ross's advice. You can also review the behaviour of the implicit keyword which will let you assign in a String-like manner while still doing validation.

i.e.:

public class PhoneNumber {

    private String number;

    public PhoneNumber(String s) {
         // validation code here, throw exception if not valid
         number = s;
    }

    public static implicit operator PhoneNumber(String s) {
         return new PhoneNumber(s);
    }
}
Michiel Buddingh'