Есть ли в С# общий числовой тип?

Мне бы очень понравился общий числовой тип, как второй тип типичного типа Func<TInput, THere, TResult>, приведенный ниже, поэтому я могу предоставить целое или двойное или десятичное число как и когда мне нравится.

var _resultSelectors = new Dictionary<string, Func<DateTime, /*here*/ double, DateTime>>();

// so I can do
_resultSelector.Add("foo", (DateTime dt, int x) => ...);
_resultSelector.Add("bar", (DateTime dt, double d) => ...);
_resultSelector.Add("gar", (DateTime dt, float f) => ...);
_resultSelector.Add("har", (DateTime dt, decimal d) => ...);

Сокращение:

  • создание моего собственного типа; или
  • использование объекта и бокса для типа значения и его распаковки; или
  • Используя ключевое слово dynamic,

Есть ли способ сделать это в С#?

Я предполагаю, что Java имеет класс Number, который, вероятно, соответствует моим требованиям, но мне было интересно, есть ли у С# что-то подобное.

Я предполагаю, что в С# нет такой вещи, но я думал, что попробую быть уверенным.

Ответ 1

Нет, нет. Дженерики и арифметические операции (+, -, *, / и т.д.) Просто не работают вместе. Это проблема, которая возникает много раз, и дизайн-проект С# никогда не рассматривался (справедливости ради, эта функция также потребует работы над CLR, как указал Эрик Липперт в ответ, связанный далее).

Вкратце, если вы проверите исходный код .NET Framework, вы увидите, что на определенном этапе разработки был интерфейс IArithmetic<T>, но он был отменен; см. здесь.

Подробнее об этом можно узнать в этом SO ответе.

Ответ 2

Даже если бы был базовый тип или интерфейс, который охватывает числовые типы, потому что вы завернули ограничение в Func, это не принесло бы вам пользы. типы ввода для Func контравариантны, поэтому его параметры не могут быть более выведены, чем заявленные.

Другими словами, вы не можете заменить Func<DateTime, ValueType, DateTime> на Func<DateTime, int, DateTime>, как вы можете, с помощью IEnumerable<T> (вы можете заменить IEnumerable<ValueType> на IEnumerable<int>)

Я думаю, что ваши лучшие ставки dynamic (по-прежнему сохраняют тип, но во время выполнения по сравнению с компиляцией) или double или decimal, если вы хотите сделать математику и не должны оставаться в тот же тип.