Я думаю, что с точки зрения удобства использования я бы выбрал тип Temperature
, а не Celsius
. Celsius
- это просто единица измерения, а Temperature
будет представлять фактическое измерение. Тогда ваш тип может поддерживать несколько единиц, таких как Цельсий, Фаренгейт и Кельвин. Я также выбрал бы десятичное в качестве резервного хранения.
Что-то в этом роде:
public struct Temperature
{
private decimal m_value;
private const decimal CelsiusToKelvinOffset = 273.15m;
public static readonly Temperature MinValue = Temperature.FromKelvin(0);
public static readonly Temperature MaxValue = Temperature.FromKelvin(Decimal.MaxValue);
public decimal Celsius
{
get { return m_value - CelsiusToKelvinOffset; }
}
public decimal Kelvin
{
get { return m_value; }
}
private Temperature(decimal temp)
{
if (temp < Temperature.MinValue.Kelvin)
throw new ArgumentOutOfRangeException("temp", "Value {0} is less than Temperature.MinValue ({1})", temp, Temperature.MinValue);
if (temp > Temperature.MaxValue.Kelvin)
throw new ArgumentOutOfRangeException("temp", "Value {0} is greater than Temperature.MaxValue ({1})", temp, Temperature.MaxValue);
m_value = temp;
}
public static Temperature FromKelvin(decimal temp)
{
return new Temperature(temp);
}
public static Temperature FromCelsius(decimal temp)
{
return new Temperature(temp + CelsiusToKelvinOffset);
}
....
}
Я бы избежал неявного преобразования, поскольку Рид утверждает, что это делает вещи менее очевидными. Однако я бы перегружал операторы (<,>, ==, +, -, *, /), так как в этом случае имеет смысл выполнять операции такого рода. И кто знает, в какой-то будущей версии .net мы можем даже указать операторные ограничения и, наконец, написать более многократно используемые структуры данных (представьте класс статистики, который может вычислять статистику для любого типа, который поддерживает +, -, *, /).