Как проверить, что я могу СУММУ значения данного типа - PullRequest
3 голосов
/ 19 января 2010

В нашем приложении есть число AggregatorTypes (идея скопирована с SQL Server), то есть MinAggregator MaxAggregator, CountAggregator и SumAggregator.

Теперь я должен проверить, поддерживает ли Aggregator тип предоставленных значений.Для графа это не важно.Для Max и Min я использую проверку на IComparable.Но что использовать для СУММ?Я попробовал конвертер, но он также поддерживает строку.

Почему нет ISummable :)

Также проверка типа IsNumeric для меня не является решением.Например, TimeSpan также может суммироваться.

Ответы [ 2 ]

1 голос
/ 20 января 2010

Вот пример метода IsSummable

public bool IsSummable(Type type)
try
{
  ParameterExpression paramA = Expression.Parameter(type, "a"), paramB = Expression.Parameter(type, "b");
  BinaryExpression addExpression = Expression.Add(paramA, paramB);
  var add = Expression.Lambda(addExpression, paramA, paramB).Compile();
  var v = Activator.CreateInstance(type);
  add.DynamicInvoke(v, v);
  return true;
}
catch
{
  return false;
}
}

и функция IsAveragable (какое странное имя :))

public bool IsAveragable(Type type)
try
{
  ParameterExpression paramA = Expression.Parameter(type, "a"), paramB = Expression.Parameter(type, "b");
        // add the parameters together
        BinaryExpression addExpression = Expression.Add(paramA, paramB);
        var avg = Expression.Parameter(typeof(int), "b");
        var conv  = Expression.Convert(avg,type);
        BinaryExpression divideExpression = Expression.Divide(paramA, conv);
        // compile it
        var add = Expression.Lambda(addExpression, paramA, paramB).Compile();
        var divide = Expression.Lambda(divideExpression, paramA, avg).Compile();
        var v = Activator.CreateInstance(type);
        add.DynamicInvoke(v, v);
        divide.DynamicInvoke(v, 1);
                    return true;
}
catch
{
  return false;
}
}

часть кода, взятого из MiscUtil Марком Гравеллом

1 голос
/ 19 января 2010

На самом деле, для мин / макс проще использовать Comparer<T>.Default, который также поддерживает IComparable<T>, обрабатывает «поднятые» операторы и т. Д.

Вы можете получить большую часть этого бесплатно, если вы используете MiscUtil ; Я написал некоторый код, который предоставляет доступ к универсальным операторам, включая универсальные методы расширения для Sum, Average и т. Д. К сожалению, операторы не могут появляться на интерфейсах, и, что еще хуже, примитивы на самом деле не имеют операторы в смысле MethodInfo (вместо этого это предоставляется непосредственно в IL) - , как обсуждено здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...