Я пытаюсь создать единицы измерения класса.Неловкий синтаксис общего метода с общим типом ограничений
То, что я до сих пор:
public abstract class UnitBase
{
protected double unitValue;
protected readonly double toSiFactor;
//more stuff goes here
}
//Meters, feet, miles etc will derive from this
public class LengthUnit : UnitBase
{
//various methods and operator overloading
//Among others there is To<> for conversions, not really needed
//to understand the problem but relevant.
public L To<L>() where L : LengthUnit, new()
{
L converted = new L();
converted.FromSi(ToSi()); //ToSi() and FromSi() are in UnitBase, omitted for brevity
return converted;
}
}
//Seconds Hours etc will derive from this
public class TimeUnit : UnitBase
{
//Add() Subtract methods and various operator overloading
}
До сих пор так хорошо. Но теперь я хочу создавать сложные типы устройств, такие как скорость. Так вот:
public class SpeedUnit<S, T> : UnitBase
where S : LengthUnit, new()
where T : TimeUnit, new()
{
//=======================
//HERE IS THE AWKWARDNESS
//=======================
public U To<U, S1, T1>()
where U : SpeedUnit<S1, T1>, new()
where S1 : LengthUnit, new()
where T1 : TimeUnit, new()
{
U converted = new U();
converted.FromSi(ToSi());
return converted;
}
}
public class Knots : SpeedUnit<NauticalMiles, Hours>
{
//omitted code
}
public class FeetPerMinute : SpeedUnit<Feet, Minutes>
{
//omitted code
}
Так вот моя проблема: Предположим, что у вас есть Узлы и вы хотите, чтобы преобразовать их в FeetPerMinute
. Что бы идеал:
Knots kts = new Knots(20);
FeetPerMinute = kts.To<FeetPerMinute>();
Вместо этого я должен сделать:
FeetPerMinute = kts.To<FeetPerMinute, Feet, Minutes>();
Это немного неудобно и может получить событие хуже, когда дело доходит до еще более сложные типы, такие как силы. To()
будет что-то вроде:
Newtons n = someForce.To<Newtons, Kilograms, Meters, Seconds>()
или даже худший, если вы сделаете ошибку, чтобы использовать тип ускорения:
Newtons n = someForce.To<Newtons, Kilograms, Acceleration<Meters, Seconds>, Meters, Seconds>()
Не очень удобно, особенно если у вас есть простота в виду. Итак, мои вопросы:
- Есть ли способ сделать эту работу? (Помимо удаления общих параметров из
SpeedUnit
) - Почему не пресловутая вывод типа работы компилятора, чтобы определить, что
Meters
иSeconds
уже есть вMetersPerSecond
?
Как насчет 'static From (U value)'? –
@OndrejTucny Ах нет, я боюсь, что это не сработает: Каков тип возврата 'From'? 'U'? Или какой-то другой тип 'U1'? Не забывайте, что я хочу конвертировать из 'Knots' (' U') в 'FeetPerMinute' (' U1'). –