Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace Diuturnal {
/// <summary>
/// Represents a UK National Insurance number.
/// </summary>
/// <remarks>
/// Based on the specification found at http://www.hmrc.gov.uk/manuals/nimmanual/NIM39110.htm.
/// </remarks>
[Serializable]
public struct NationalInsuranceNumber {
private const string ValidationString = @"^[A-Z-[DFIQUV]][A-Z-[DFIOQUV]][0-9]{6}[A-D]$";
private static readonly Regex _validator = new Regex(ValidationString);
public static readonly NationalInsuranceNumber Empty = new NationalInsuranceNumber(string.Empty);
private string _number;
private NationalInsuranceNumber(string number) {
Debug.Assert(0 == number.Length || 9 == number.Length);
_number = number;
}
/// <summary>
/// Converts the instance of the NI number to its equivalent string representation.
/// </summary>
/// <returns>The string representation of the NI number.</returns>
public override string ToString() {
return _number;
}
public override bool Equals(object obj) {
if (!(obj is NationalInsuranceNumber)) {
return false;
}
return (this == (NationalInsuranceNumber) obj);
}
public override int GetHashCode() {
return this.ToString().GetHashCode();
}
public static bool operator ==(NationalInsuranceNumber lhs, NationalInsuranceNumber rhs) {
return (lhs.ToString() == rhs.ToString());
}
public static bool operator !=(NationalInsuranceNumber lhs, NationalInsuranceNumber rhs) {
return !(lhs == rhs);
}
/// <summary>
/// Converts the string representation of an NI number to an instance of the <see cref="NationalInsuranceNumber"/> class.
/// </summary>
/// <param name="s">A string containing an NI number to convert.</param>
/// <returns>A <see cref="NationalInsuranceNumber"/> object equivalent to the NI number contained in <i>s</i>.</returns>
/// <exception cref="ArgumentNullException"><i>s</i> is <see langword="null"/>.
/// </exception>
/// <exception cref="FormatException"><i>s</i> does not represent a valid UK NI number.</exception>
/// <remarks>The validation check will strip out spaces before performing its check.
/// <c>AB123456C</c> and <c>AB 12 34 56 C</c> will both be accepted, for example.</remarks>
public static NationalInsuranceNumber Parse(string s) {
if (null == s) {
throw new ArgumentNullException();
}
string filteredText = s.Replace(" ", "").ToUpper();
if (!_validator.IsMatch(filteredText)) {
throw new FormatException("Supplied parameter is not a valid National Insurance number.");
}
return new NationalInsuranceNumber(filteredText);
}
/// <summary>
/// Converts the string representation of an NI number to an instance of the <see cref="NationalInsuranceNumber"/> class.
/// A return value indicates whether the operation succeeded.
/// </summary>
/// <param name="s">A string containing an NI number to convert.</param>
/// <param name="result">When this method returns, contains the <see cref="NationalInsuranceNumber"/> instance
/// equivalent to the NI number contained in <i>s</i>, if the conversion succeeded, or <see cref="NationalInsuranceNumber.Empty"/>
/// if the conversion failed. The conversion fails if the <i>s</i> parameter is <see langword="null"/>,
/// or is not of the correct format. This parameter is passed uninitialised.</param>
/// <returns><b>true</b> if <i>s</i> was converted successfully; otherwise, <b>false</b>.</returns>
/// <remarks>The <b>TryParse</b> method is like the <see cref="Parse"/> method, except the <b>TryParse</b>
/// method does not throw an exception if the conversion fails.</remarks>
public static bool TryParse(string s, out NationalInsuranceNumber result) {
if (null == s) {
result = NationalInsuranceNumber.Empty;
return false;
}
string filteredText = s.Replace(" ", "").ToUpper();
if (!_validator.IsMatch(filteredText)) {
result = NationalInsuranceNumber.Empty;
return false;
}
result = new NationalInsuranceNumber(filteredText);
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.