Я работаю, разрабатывая систему прямо сейчас, которая имеет дело с большим количеством преобразований между семантически различными значениями, которые имеют тот же примитивный тип.NET (удваивать/представлять в виде строки/интервал). Это означает, что возможно запутаться, о котором 'семантический тип' Вы используете, или не преобразовывая или преобразовывая слишком много раз. Идеально я хотел бы, чтобы компилятор выдал предупреждение, если я пытаюсь использовать значение, где он семантически не имеет смысла.
Некоторые примеры для указания на то, к чему я обращаюсь:
double
.Vector3D
структура.Я полагаю, что F# имеет решение времени компиляции для этого (названный единицами измерения.) я хотел бы сделать что-то подобное в C#, хотя мне не нужен размерный анализ, который предлагают единицы измерения в F#.
Я полагаю, что C++ мог достигнуть этого использования typedef
(хотя я не эксперт C++).
Очевидное решение состоит в том, чтобы перенести double/string/whatever в новый тип, чтобы дать ему информацию о типе потребности компилятора. Мне любопытно, если у кого-либо есть альтернативное решение. Если Вы действительно думаете, переносясь, единственный / лучший способ, то войдите в некоторые оборотные стороны шаблона (и любые позитивные аспекты, которые я не упомянул также.) я особенно обеспокоен производительностью абстрактных примитивных числовых типов на моих вычислениях во времени выполнения, таким образом независимо от того, что решение, которое я предлагаю, должно быть легким и с точки зрения выделения памяти и с точки зрения отправки вызова.
Мне действительно интересно, как компилятор выдает предупреждение, когда вы смешиваете радианы и градусы. Они оба двойные? Вы находитесь в мире ООП, поэтому вам следует идти этим путем. Два предложения:
Degree
, Radian
и определите правила преобразования. Или создайте класс «Угол» и храните в нем всю информацию о единицах измерения и преобразованиях. Думаю, вы можете создать две разные структуры для принудительной проверки типов. В следующем коде я добавил неявное приведение от радианов к double и явное приведение от degress к радианам. Вы можете использовать любой набор неявных и явных операторов, но я думаю, что те, которые я определил здесь, будут работать хорошо, поскольку структура Radians может быть передана непосредственно в функции Math
.
public struct Degrees
{
private double m_Value;
public static explicit operator Radians(Degrees rhs)
{
return rhs.m_Value * (Math.Pi / 180);
}
}
public struct Radians
{
private double m_Value;
public static implicit operator double(Radians rhs)
{
return rhs.m_Value;
}
}
Я никогда не находил удовлетворительного решения этой проблемы в C #. Просто кажется, что система типов не была предназначена для этого варианта использования. Если бы у меня была такая же потребность сейчас, я бы изучил подход единиц измерения F #.