2016-06-29 3 views
10

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

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) => ...); 

Короткие:

  1. делает свой собственный тип; или
  2. с использованием объекта и бокса типа значения и его распаковки; или
  3. Использование dynamic ключевого слова,

Есть правильный способ сделать это в C#?

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

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

+0

Если у вас может быть все 4, я бы предложил вам выбрать один из «double» или «decimal» (в зависимости от вашего варианта использования, то есть с плавающей точкой) и преобразовать остальное в это. –

+0

@CharlesMager Это хорошая идея. –

+0

Нет никакого общего интерфейса, но у вас все еще будет проблема поиска правильных функций для вызова на основе типа времени выполнения. Откуда берутся конкретные числовые значения? – Lee

ответ

11

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

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

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

5

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

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

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

+0

'Func' имеет отклонение. Его входные параметры контравариантны, а его выход ковариантен. Вот определение конкретной перегрузки, которую я использую: public 'delegate TResult Func <в T1, в T2, вне TResult> (T1 arg1, T2 arg2);' –

+0

О, извините, я снова перечитаю ваше сообщение. Ты прав. Из-за контравариантности его типов ввода фактические закрытые общие параметры не могут быть более выведены, чем их типы времени компиляции. –

Смежные вопросы