是否可以将 Enumerable.Sum() 扩展与动态类型一起使用
本文关键字:动态 类型 一起 扩展 Enumerable Sum 是否 | 更新日期: 2023-09-27 18:33:53
在我的项目中,我正在使用Telerik RadGridView控件,其ItemSource是动态对象列表(派生自DynamicObject)。
我计划使用AggregateFunctions,如SumFunction,MinFunction,但它在列中崩溃,这些列从动态属性中获取值。如果我是对的,那是因为Linq扩展,而不是Telerik。
此问题是否有任何解决方法?
更新
模型类如下所示
public class SampleModel : DynamicObject
{
// some properties
}
来源如下:
myGrid.ItemsSource = new List<SampleModel> { // some model items };
XAML 是:
<telerik:RadGridView ShowColumnFooters="True" AutoGenerateColumns="False" x:Name="myGrid">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding p1}">
<telerik:GridViewDataColumn.AggregateFunctions>
<telerik:SumFunction />
</telerik:GridViewDataColumn.AggregateFunctions>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
其中 p1 是动态属性
异常消息为:
类型"System.Linq.Enumerable"上没有泛型方法"Sum"与提供的类型参数和参数兼容。如果该方法是非泛型的,则不应提供类型参数。
我通过创建自己的聚合函数并在其中手动构建表达式来解决此问题(来源:Telerik 支持)。
Sum() 函数的代码是:
public class CustomSumFunction : EnumerableSelectorAggregateFunction
{
protected override string AggregateMethodName
{
get { return "Sum"; }
}
protected override Type ExtensionMethodsType
{
get
{
return typeof(CustomAggregateFunctions);
}
}
}
public static class CustomAggregateFunctions
{
public static TValue Sum<T, TValue>(IEnumerable<T> source, Func<T, TValue> selector)
{
return source.Select(selector).Aggregate((t1, t2) =>
{
Expression expr = Expression.Add(Expression.Constant(t1, t1.GetType()), Expression.Constant(t2, t2.GetType()));
Expression conversion = Expression.Convert(expr, typeof(TValue));
return Expression.Lambda<Func<TValue>>(conversion).Compile()();
});
}
public static decimal? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, decimal?> selector)
{
return source.Sum(selector);
}
public static decimal Sum<TSource>(IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
return source.Sum(selector);
}
public static double? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, double?> selector)
{
return source.Sum(selector);
}
public static double Sum<TSource>(IEnumerable<TSource> source, Func<TSource, double> selector)
{
return source.Sum(selector);
}
public static float? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, float?> selector)
{
return source.Sum(selector);
}
public static float Sum<TSource>(IEnumerable<TSource> source, Func<TSource, float> selector)
{
return source.Sum(selector);
}
public static int? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, int?> selector)
{
return source.Sum(selector);
}
public static int Sum<TSource>(IEnumerable<TSource> source, Func<TSource, int> selector)
{
return source.Sum(selector);
}
public static long? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, long?> selector)
{
return source.Sum(selector);
}
public static long Sum<TSource>(IEnumerable<TSource> source, Func<TSource, long> selector)
{
return source.Sum(selector);
}
}