Как бы вы реорганизовали это, имея в виду, что вам нужно представить еще десятки таких измерений? Это похоже на изменение типа int на short, long или byte. Универсальный unit<T>? Неявное преобразование типа с помощью перегрузки оператора? ToType() шаблон? Абстрактный базовый класс? IConvertible?
public class lb
{
private readonly float lbs;
private readonly kg kgs;
public lb(float lbs)
{
this.lbs = lbs;
this.kgs = new kg(lbs * 0.45359237F);
}
public kg ToKg()
{
return this.kgs;
}
public float ToFloat()
{
return this.lbs;
}
}
public class kg
{
private readonly float kgs;
private readonly lb lbs;
public kg(float kgs)
{
this.kgs = kgs;
this.lbs = new lb(kgs * 2.20462262F);
}
public float ToFloat()
{
return this.kgs;
}
public lb ToLb()
{
return this.lbs;
}
}





Думаю, я просто превращу его в struct, который по крайней мере большинство примитивов.
Ага, значит, вам нужен тип, допускающий значение NULL. Это цифры. Единственная проблема, с которой я столкнулся с вашим текущим дизайном, - это тесная связь между фунтами и килограммами; что, если в будущем я захочу ввести тонну, тонну, ньютон, унцию, грамм и т. д.?
Я бы не стал создавать отдельные классы для каждого веса. Вместо этого имейте один класс, представляющий единицу, а другой - число с единицей:
/// <summary>
/// Class representing a unit of weight, including how to
/// convert that unit to kg.
/// </summary>
class WeightUnit
{
private readonly float conv;
private readonly string name;
/// <summary>
/// Creates a weight unit
/// </summary>
WeightUnit(float conv, string name)
{
this.conv = conv;
this.name = name;
}
/// <summary>
/// Returns the name of the unit
/// </summary>
public string Name { get { return name; } }
/// <summary>
/// Returns the multiplier used to convert this
/// unit into kg
/// </summary>
public float convToKg { get { return conv; } }
};
/// <summary>
/// Class representing a weight, i.e., a number and a unit.
/// </summary>
class Weight
{
private readonly float value;
private readonly WeightUnit unit;
public Weight(float value, WeightUnit unit)
{
this.value = value;
this.unit = unit;
}
public float ToFloat()
{
return value;
}
public WeightUnit Unit
{
get { return unit; }
}
/// <summary>
/// Creates a Weight object that is the same value
/// as this object, but in the given units.
/// </summary>
public Weight Convert(WeightUnit newUnit)
{
float newVal = value * unit.convToKg / newUnit.convToKg;
return new Weight(newVal, newUnit);
}
};
Приятно то, что вы можете создавать все WeightUnits как одноэлементные объекты из данных, возможно, XML-файла или ресурса, так что вы можете добавить новую единицу, вообще не меняя код. Создание объекта Weight - это просто поиск правильного синглтона по имени.
Я ненавижу тот факт, что мне приходится использовать System.Nullable <> (например, использовать?) Для представления нулевых структур. Ресурсы, которые можно сэкономить с помощью структуры, в этом сценарии менее важны, чем дизайн.