Я использую эту идею для создания своего рода внутренней грамматики для проекта, который имеет дело с физическими мерами.Сначала я сомневался в таком подходе, но сейчас он мне действительно нравится, поскольку он делает исходный код очень читабельным, легким и приятным для написания.Вот пример:
A Тип устройства:
public struct Celsius : IEquatable<Celsius>
{
private readonly Double _value;
public const string Abbreviation = "°C";
public Celsius(Double value)
{
_value = value;
}
public Boolean Equals(Celsius other)
{
return _value == other._value;
}
public override Boolean Equals(Object other)
{
if (!(other is Celsius))
{
return false;
}
return Equals((Celsius)other);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public override string ToString()
{
return _value + Abbreviation;
}
public static explicit operator Celsius(Double value)
{
return new Celsius(value);
}
public static explicit operator Double(Celsius value)
{
return value._value;
}
public static Boolean operator >(Celsius l, Celsius r)
{
return l._value > r._value;
}
public static bool operator <(Celsius l, Celsius r)
{
return l._value < r._value;
}
public static Boolean operator >=(Celsius l, Celsius r)
{
return l._value >= r._value;
}
public static bool operator <=(Celsius l, Celsius r)
{
return l._value <= r._value;
}
public static Boolean operator ==(Celsius l, Celsius r)
{
return l._value == r._value;
}
public static bool operator !=(Celsius l, Celsius r)
{
return l._value != r._value;
}
}
Расширение класса устройства:
public static class UnitsExtensions
{
public static Celsius Celsius(this Double value)
{
return new Celsius(value);
}
public static Celsius Celsius(this Single value)
{
return new Celsius(value);
}
public static Celsius Celsius(this Int32 value)
{
return new Celsius(value);
}
public static Celsius Celsius(this Decimal value)
{
return new Celsius((Double)value);
}
public static Celsius? Celsius(this Decimal? value)
{
return value == null ? default(Celsius?) : new Celsius((Double)value);
}
}
Использование:
var temp = (Celsius)value;
if (temp <= 0.Celsius())
{
Console.Writeline("It's cold!");
}
else if (temp < 20.Celsius())
{
Console.Writeline("Chilly...");
}
else if (temp < 30.Celsius())
{
Console.Writeline("It's quite lovely");
}
else
{
Console.Writeline("It's hot!");
}
У меня есть несколько этих типов для различных мер, таких как Millimeter
, Radians
, Degrees
, MillimetersPerSecond
и т. Д. Я даже ушелнастолько, чтобы реализовать деление так, чтобы, когда я делю, скажем, MillimetersPerSecond
на Millimeters
, я получал взамен TimeSpan
значение.Возможно, это за бортом, но я нашел безопасность типов и умственную простоту использования типов, стоящих усилий для их внедрения и обслуживания.