При расширении системы типов.NET, таким образом, компилятор осуществляет семантическое значение примитивных значений в определенных случаях

Я работаю, разрабатывая систему прямо сейчас, которая имеет дело с большим количеством преобразований между семантически различными значениями, которые имеют тот же примитивный тип.NET (удваивать/представлять в виде строки/интервал). Это означает, что возможно запутаться, о котором 'семантический тип' Вы используете, или не преобразовывая или преобразовывая слишком много раз. Идеально я хотел бы, чтобы компилятор выдал предупреждение, если я пытаюсь использовать значение, где он семантически не имеет смысла.

Некоторые примеры для указания на то, к чему я обращаюсь:

  • Углы могут быть в единицах градусов или радианов, все же оба представлены double.
  • Векторные положения могут быть в локальных / глобальных координатах, все же оба представлены a Vector3D структура.
  • Вообразите библиотеку SQL, которая принимает различные параметры запроса как строки. Было бы хорошо иметь способ осуществить, это только убирает, строкам позволили быть переданными в во времени выполнения, и единственный способ получить чистую строку состоял в том, чтобы пройти через некоторую логику предотвращения атаки с использованием кода на SQL.

Я полагаю, что F# имеет решение времени компиляции для этого (названный единицами измерения.) я хотел бы сделать что-то подобное в C#, хотя мне не нужен размерный анализ, который предлагают единицы измерения в F#.

Я полагаю, что C++ мог достигнуть этого использования typedef (хотя я не эксперт C++).

Очевидное решение состоит в том, чтобы перенести double/string/whatever в новый тип, чтобы дать ему информацию о типе потребности компилятора. Мне любопытно, если у кого-либо есть альтернативное решение. Если Вы действительно думаете, переносясь, единственный / лучший способ, то войдите в некоторые оборотные стороны шаблона (и любые позитивные аспекты, которые я не упомянул также.) я особенно обеспокоен производительностью абстрактных примитивных числовых типов на моих вычислениях во времени выполнения, таким образом независимо от того, что решение, которое я предлагаю, должно быть легким и с точки зрения выделения памяти и с точки зрения отправки вызова.

6
задан Drew Noakes 5 June 2010 в 02:13
поделиться

3 ответа

Мне действительно интересно, как компилятор выдает предупреждение, когда вы смешиваете радианы и градусы. Они оба двойные? Вы находитесь в мире ООП, поэтому вам следует идти этим путем. Два предложения:

  1. Используйте только одну единицу внутри, я думаю, радианы лучше. Затем конвертируйте только при вводе / выводе. \
  2. Создайте структуры Degree , Radian и определите правила преобразования. Или создайте класс «Угол» и храните в нем всю информацию о единицах измерения и преобразованиях.
3
ответ дан 17 December 2019 в 02:24
поделиться

Думаю, вы можете создать две разные структуры для принудительной проверки типов. В следующем коде я добавил неявное приведение от радианов к 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;    
  }
}
3
ответ дан 17 December 2019 в 02:24
поделиться

Я никогда не находил удовлетворительного решения этой проблемы в C #. Просто кажется, что система типов не была предназначена для этого варианта использования. Если бы у меня была такая же потребность сейчас, я бы изучил подход единиц измерения F #.

0
ответ дан 17 December 2019 в 02:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: