如何检查我是否可以使用给定类型的SUM值

在我们的应用程序中,我们有许多AggregatorTypes(从SQL Server复制的想法),即MinAggregator MaxAggregator,CountAggregator和SumAggregator。

现在我应该检查Aggregator是否支持提供的值的类型。 对于伯爵来说,这并不重要。 对于Max和Min,我使用检查IComparable。 但是什么用于SUM? 我尝试过Converter但它也支持字符串。

为什么没有ISummable 🙂

IsNumeric就像检查一样对我来说也不是解决方案。 例如TimeSpan也可以求和。

实际上,对于min / max,使用Comparer.Default更容易,它也支持IComparable ,处理“提升”操作符等。

如果您使用MiscUtil ,您可以免费获得大部分内容; 我编写了一些代码,提供对generics运算符的访问,包括SumAverage等的通用扩展方法。不幸的是,运算符不能出现在接口上,更糟糕的是原语在MethodInfo意义上实际上没有运算符(这在IL中直接提供) – 如这里所讨论的 。

这是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; } } 

部分代码取自Marc Gravell的MiscUtil