Alternatively, you could not use value types for your fields. For instance, you could create a "FirstName" class with the following implementation:
public class FirstName
{
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException("Value cannot be null");
if (value.Length > 128)
throw new ArgumentOutOfRangeException("Value cannot be longer than 128 characters");
_Value = value;
}
}
public FirstName(string initialValue)
{
Value = initialValue; //does validation check even in constructor
}
}
Finally, in your code sample above you would simply have:
public interface IPersonInfo
{
FirstName FirstName { get; set; }
String LastName { get; set; }
}
and so on with your other properties.
Then to use the property in your codel, you would have:
public FirstName MyFirstName;
var x = MyFirstName.Value;
If you have a lot of fields that you want to validate, this might end up being a cumbersome approach. However, you could generalize it to handle certain types of numbers - like positive numbers (ints > 0
), or counts (int >= 0
), measures, etc.
Strings are harder because they often have length restrictions in addition to value types (such as no special characters, no digits, etc. This might be possible to accomodate by having a read-only length property that is set in the constructor of the inheriting class.