【发布时间】:2017-12-10 07:16:00
【问题描述】:
我正在抽象一些代码,但遇到了将 Func 的结果转换为整数进行比较的问题。
我有一个函数:
public static IConvertible GetIllnessRateByParity(IEnumerable<ILLNESS_OBJECT> pItems, int pParity, Func<ILLNESS_OBJECT, IConvertible> pSelector)
{
var filtered = pItems.Where(a => a.Parity == pParity);
return Math.Round(filtered.Count(a => Convert.ToInt32(pSelector(a)) == 1) / (double)GetBirthCountByParity(pItems, pParity), 2);
}
public class ILLNESS_OBJECT
{
public int ID { get; set; }
public DateTime Day { get; set; }
public int Parity { get; set; }
public int Afterbirth { get; set; }
public int OvaryInfection { get; set; }
etc...
}
计算一组数据中特定疾病的发病率。要分析的疾病是通过选择器输入的,该选择器从 ILLNESS_OBJECT 对象中选择一个 IConvertible 值。
我这样调用方法:
GetIllnessRateByParity(data, 1, a => a.AfterBirth)
data 是一个具有非空值的 IEnumerable。
该方法在 Convert.ToInt32(pSelector(a)) 部分引发 InvalidCastException ,但没有明确说明此转换失败的原因,有人可以向我解释一下吗?我的印象是 pSelector(a) 返回一个与 int 兼容的 IConvertible 值,对吧?任何帮助将不胜感激!
编辑:异常消息: CONFIDENTIAL.CLASS.dll 中出现“System.InvalidCastException”类型的异常,但未在用户代码中处理
消息:指定的转换无效。
【问题讨论】:
-
异常中没有任何额外信息?例如,出现异常的消息是什么?
-
你检查过你的pSelector返回的IConvertible的具体实现了吗?可能是不支持 ToInt32 / 的实现在那里抛出异常?
-
“我的印象是 pSelector(a) 返回一个与 int 兼容的 IConvertible 值” - 我不认为是这种情况,但我也不认为是这样重要的。正在发生的事情是它正在调用
ToInt32的以下重载:msdn.microsoft.com/en-us/library/23511zys(v=vs.110).aspx,然后按照 Jeroen 所说的去做。 -
为什么不把
Func<ILLNESS_OBJECT, IConvertible> pSelector改成Func<ILLNESS_OBJECT, int> pSelector? -
没有采用 IConvertable 的 Convert.ToInt32 的重载,这就是运行时将回退到调用 @Chris 指出的重载的原因。你也用函数式编程标记了这个问题,但是你使用的接口比函数式更 OOP,Roman 的想法更实用。而且你的班级有可变字段。
标签: c# linq generics casting functional-programming