如何检查,我可以和给出类型的值类型

2023-09-03 21:05:00 作者:易生峰光

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

In our application we have number of AggregatorTypes (idea copied from SQL Server) i.e. MinAggregator MaxAggregator, CountAggregator, And SumAggregator.

现在我要检查,如果聚合支持提供的值的类型。对于计数这并不重要。对于最大和最小我使用检查IComparable的。 但是,用什么SUM? 我试着转换器,但它也支持字符串。

Now I should check if Aggregator supports type of provided values. For Count it is not important. For Max and Min I use checking for IComparable. But what to use for SUM? I tried Converter but it also supports string.

为什么没有ISummable :)

Why there is no ISummable :)

另外则IsNumeric类似检查是不是对我一个解决方案。例如时间跨度也可以总结。

Also IsNumeric like checking is not a solution for me. For example TimeSpan also can sum.

推荐答案

下面是一个示例IsSummable方法

Here is sample IsSummable method

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功能(有什么奇怪的名字:))

and IsAveragable function (what a weird name:) )

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

由马克Gravell从MiscUtil采取的code部分

part of the code taken from MiscUtil by Marc Gravell