Есть ли в C# интерфейс для интервальных значений?

Я делаю расширение интервала коллекции знаменитой библиотеки C# C5. IInterval Интерфейс определяет интервал с сопоставимыми конечными точками (нерелевантные элементы удалены):

public interface IInterval<T> where T : IComparable<T>
{
    T Low { get; }
    T High { get; }
}

В целом, это хорошо работает, поскольку конечные точки интервала могут быть чем угодно, например, целыми числами, датами или даже строками.

Однако иногда выгодно иметь возможность рассчитать продолжительность интервала. Интервал [3:5) имеет длительность 2 и интервал [1PM, 9PM) имеет продолжительность 8 часов. Это невозможно с сопоставимыми данными, так как это дает нам только порядок элементов, а не их расстояние, например, трудно определить расстояние между двумя строками. Тип конечной точки в основном должен быть масштабированными значениями.

Есть ли такой интерфейс IComparable<T>Это позволяет мне сравнивать конечные точки в целом, но также выполнять такие вещи, как вычитание двух конечных точек, чтобы получить длительность, и добавление длительности к нижней конечной точке, чтобы получить верхнюю конечную точку, которая может использоваться для наследующего интерфейса, IDurationInterval<T> : IInterval<T> например?

Или более кратко: есть ли интерфейс для интервальных значений?

1 ответ

Решение

Такой интерфейс не существует. В некоторых языках, таких как Scala, есть абстракции над такими операциями, а в.NET - нет. Кроме того, я обнаружил, что разработчики библиотек.NET довольно консервативны в том, что касается добавления уровней абстракции: кажется, что они предпочитают простые и конкретные, а не сложные и абстрактные. Они никогда не добавляли эту абстракцию, по-видимому, потому что никогда не было острой необходимости в ней ни в одной из библиотек.NET Framework. Кроме того, это абстракция, которая может вызвать много накладных расходов при неправильном использовании.

Однако ничто в системе типов.NET не исключает такой интерфейс. Для этого потребуются два параметра типа вместо одного: один для реализующего типа и один для результирующего типа. Самый простой интерфейс может выглядеть так:

interface IAlgebraic<T, R> {
  T Add(R value)
  R Subtract(T value)
}

К сожалению, нет возможности добавить этот интерфейс к существующим типам, таким как Int32 и DateTime. Для этих типов вам понадобится следствие IComparable<T>"s Comparer<T>,

interface IAlgebraicOps<T, R> {
  T Add(T x, R y)
  R Subtract(T x, T y)
}
Другие вопросы по тегам