C#如何编写兼容不同类类型的通用子报头设置函数
问题原因
你编写的泛型方法未给类型参数T添加约束,编译器默认T为System.Object类型,自然无法识别FindControl方法。同时你原有代码中FindControl返回的控件类型是XRSubreport,你在泛型方法里错误转换为XtraReport,这也会导致运行时转换错误。
可行实现方案
方案1:添加泛型约束(最推荐)
你用到的所有报表类均为DevExpress的XtraReport子类,直接给泛型参数添加对应约束即可,修正后的代码如下:
public static T SetEventHeader<T>(T oRpt , Guid studyPK) where T : XtraReport { var subReport = new XRptEventHeader(); var eventHeaderList = FreqReports.GetEventHeaderList(studyPK); // 修正类型转换错误,改为转XRSubreport var dataSourceSubReport = (XRSubreport)oRpt.FindControl("xrSubreportSite", false); dataSourceSubReport.ReportSource = subReport; dataSourceSubReport.ReportSource.DataSource = eventHeaderList; return oRpt; }
调用时不需要额外改动,编译器会自动校验传入的参数是否为XtraReport子类。
方案2:传入查找子报表的委托(无共同基类时适用)
如果确实存在部分oRpt类型没有继承XtraReport,可以把查找控件的逻辑通过委托传入,完全适配不同类型的查找逻辑:
public static T SetEventHeader<T>(T oRpt, Guid studyPK, Func<T, XRSubreport> findSubreportFunc) { var subReport = new XRptEventHeader(); var eventHeaderList = FreqReports.GetEventHeaderList(studyPK); var dataSourceSubReport = findSubreportFunc(oRpt); dataSourceSubReport.ReportSource = subReport; dataSourceSubReport.ReportSource.DataSource = eventHeaderList; return oRpt; }
调用示例:
// 针对XtraReport子类的调用 SetEventHeader(yourReport, studyPk, rpt => (XRSubreport)rpt.FindControl("xrSubreportSite", false)); // 其他自定义类型的调用,按需实现查找逻辑即可 SetEventHeader(customReport, studyPk, rpt => rpt.CustomFindSubreportMethod());
方案3:使用dynamic类型(不推荐,仅做临时快速修复用)
如果不想修改调用逻辑,也可以用dynamic绕过编译时类型检查,缺点是丢失编译时校验,运行时可能抛出异常:
public static T SetEventHeader<T>(T oRpt , Guid studyPK) { var subReport = new XRptEventHeader(); var eventHeaderList = FreqReports.GetEventHeaderList(studyPK); dynamic dynamicRpt = oRpt; var dataSourceSubReport = (XRSubreport)dynamicRpt.FindControl("xrSubreportSite", false); dataSourceSubReport.ReportSource = subReport; dataSourceSubReport.ReportSource.DataSource = eventHeaderList; return oRpt; }
内容的提问来源于stack exchange,提问作者done_merson
相关产品推荐
相关产品推荐

