为什么以下代码不起作用?我收到以下错误。
无法将类型'V'隐式转换为int。
private ObservableCollection<DataItem> method<T, V>(DataTable dt, SeriesItem seriesItem, FilterValues filter, ObservableCollection<DataItem> chart)
{
var result = from t in dt.AsEnumerable()
group t by new { type = t.Field<T>(seriesItem.LabelMapping).ToString().ToUpper() } into g
orderby g.Key.type
select new
{
Item_Type = g.Key.type.ToString(),
Amount = seriesItem.IsSum
? g.Sum(s => s.Field<V>(seriesItem.ValueMapping))
: g.Count()
};
foreach (var g in result)
{
chart.Add(new DataItem(g.Item_Type, double.Parse(g.Amount.ToString()))
{
IsSum = seriesItem.IsSum,
IsDisplayCurrency = seriesItem.IsDisplayCurrency
});
}
return chart;
}
答案 0 :(得分:0)
g.Count()
返回一个int
IsSum ? g.Sum() : g.Count()
必须是int
所以g.Sum()
必须是int
所以V
必须是int
除了这个演绎之外没有任何东西可以阻止V成为decimal
或其他任何内容,因此编译错误消息。
修复:以下任何一个:
V
并获取int结果g.Count()
最后一个有一个额外的好处,你可以在以后的方法中删除双转换代码。
@Daniel Renshaw
List<decimal> source = new List<decimal>();
int result = source.Sum<decimal>(); //compile error
//Cannot implicitly convert type 'decimal' to 'int'
答案 1 :(得分:0)
问题在于你试图总结所有V型值。
s.Field<V>(...)
返回类型为V的值,因此选择器匿名函数s => s.Field<V>(...)
也返回类型为V的值。但是,g.Sum(...)
需要一个返回值为1的选择器函数以下类型:decimal
,double
,float
,int
,long
(或其可以为空的对应方)。无法从类型V隐式转换为任何类型。
如果值映射列始终是特定类型,则显式使用该类型而不是泛型类型V.
答案 2 :(得分:0)
查看你的代码,我猜这段代码会返回一个类型为V的值:
s => s.Field<V>(seriesItem.ValueMapping)
如果是这种情况,假设对类型V没有约束(可能是任何东西,对象,字符串等等),编译器将无法确定哪个重载{{3}调用方法,因此编译错误。
假设V的类型仅在运行时已知(因此您不能简单地将V约束为int / decimal / double等)如何向该方法添加委托,您可以使用该委托从一个对象返回一个int V型? e.g:
private ObservableCollection<DataItem> method<T, V>(DataTable dt, SeriesItem seriesItem, FilterValues filter, ObservableCollection<DataItem> chart, Func<V, int> convertV)
{
var result = from t in dt.AsEnumerable()
group t by new { type = t.Field<T>(seriesItem.LabelMapping).ToString().ToUpper() } into g
orderby g.Key.type
select new
{
Item_Type = g.Key.type.ToString(),
Amount = seriesItem.IsSum ? g.Sum(s => convertV(s.Field<V>(seriesItem.ValueMapping))) : g.Count()
};
然后你将责任推送给调用者(它会知道类型T和V)以找出如何将V转换为int。