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

时间:2010-01-19 11:59:35

标签: c# .net reflection

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

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

为什么没有ISummable :)

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

2 个答案:

答案 0 :(得分:1)

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

如果你使用MiscUtil,你可以免费获得大部分内容。我编写了一些代码来提供对泛型运算符的访问,包括SumAverage等的通用扩展方法。不幸的是,运算符不能出现在接口上,更糟糕的是原语不会实际上具有MethodInfo意义上的运算符(这在IL中直接提供) - as discussed here

答案 1 :(得分:1)

以下是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 by Marc Gravell