![](/img/trans.png)
[英]Type.GetMethod() for polymorphic method (both generic and non-generic)
[英]Generic override method in in Polymorphic object
我在多態基類中使用泛型覆蓋方法的語法有問題。
這是用於報告引擎的基本架構; 我在基類中有兩個虛擬方法和從基類派生的大量對象,它們覆蓋了這些方法。
在客戶端代碼中,會調用報表工廠對象,該對象根據傳入的字符串以及用作參數的對象數組來實例化其中一個對象。 方法的字符串名稱來自數據庫並位於多選列表中,因此用戶可以選擇要運行的任意數量的報告。
現在的要求是創建 PDF 文檔,這很容易做到,因為該通用方法具有單一已知類型。 我想做的是擴展它的用處並返回任何類型的列表。
這是我的虛擬方法的簽名。 第一個是強類型的,我可以完美地工作,第二個,我有問題。 他們來了:
/// <summary>
/// Virtual method to run report from a Word mail merge template
/// </summary>
/// <param name="Template">Word mail merge template name</param>
/// <returns>PDF Document</returns>
public virtual PdfDocument RunReportPDFOutFromWordTemplate( string TemplateName )
{
try
{
return new PdfDocument();
}
catch( Exception )
{
throw;
}
}
/// <summary>
/// Virtual method to run report outputting a generic list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public virtual List<T> RunReportListOut<T>()
{
try
{
return new List<T>();
}
catch( Exception )
{
throw;
}
}
然后在我的代碼中,我通過調用 ReportFactory 類來調用該對象。 首先是 ReportFactory 類,然后是調用代碼:
public static class ReportFactory
{
/// <summary>
/// Get an object from the Report Factory
/// </summary>
/// <param name="ObjectName">Name of the Object</param>
/// <param name="ParamList">List of parameters the object constructor is expecting</param>
/// <returns></returns>
public static ReportBase GetObject( string ObjectName, object[] ParamList )
{
try
{
return (ReportBase)Activator.CreateInstance( Type.GetType( Utils.GetCurrentNamespaceName() + "." + ObjectName ), ParamList );
}
catch( Exception )
{
throw;
}
}
}
現在是調用代碼:
ParamList = new object[] { r.Name, r.MethodPointer, this.dpStartDate.SelectedDate, this.dpEndDate.SelectedDate, this.AppData.ActivePatient };
rb = ReportFactory.GetObject( r.MethodPointer, ParamList );
PdfDocument pdfDoc = rb.RunReportPDFOutFromWordTemplate( ConfigurationManager.AppSettings[ "ReportTemplateLocation" ].ToString() + r.MethodPointer + ConfigurationManager.AppSettings[ "ReportTemplateType" ].ToString() );
有效方法的代碼在這里並不真正相關,我不想通過發布它來浪費任何人的時間。 它適用於我需要它做的事情。
問題是我希望能夠使用相同的報告工廠返回列表。 當我覆蓋我的方法時,我收到以下錯誤: Cannot implicitly convert type 'System.Collections.Generic.List<FMCNA_Model.Cycle>' to 'System.Collections.Generic.List<Cycle>
這是覆蓋的代碼和輔助方法:
public override List<Cycle> RunReportListOut<Cycle>()
{
try
{
List<Cycle> CycleList = this.GetCycleList();
return CycleList;
}
catch( Exception )
{
throw;
}
}
private List<Cycle> GetCycleList()
{
try
{
return Cycle.PatientForDateRange( this.CurrentPatient.PatientIDInternal, this.StartDate, this.EndDate );
}
catch( Exception )
{
throw;
}
}
我在這里很難過如何做到這一點。 抱歉,這個問題太長了,我認為最好將所有內容都集中在覆蓋語法上。
謝謝,
麥克風
正如 SLaks 所說,您在嘗試使用名為T
的類型參數聲明泛型虛方法時遇到了問題 - 但隨后您嘗試使用另一個泛型方法使用Cycle
作為類型參數來覆蓋它。 這真的不是你的意思。 泛型方法意味着調用者獲得指定類型的說法-而想必你只是想返回一個List<Cycle>
。
我強烈懷疑您應該有一個泛型type ,帶有使用該類型參數的方法聲明。 例如:
public abstract class Report<T>
{
public abstract List<T> RunReportListOut();
}
然后
public class CycleReport : Report<Cycle>
{
public override List<T> RunReportListOut()
{
...
}
}
如果您想要兩種類型,以不同的方式命名它們會更清晰……然后您需要在您的方法中添加一個轉換。 或者,只需將兩種類型合並為一種,這可能會更干凈。
此外,正如我在評論中指出的,您應該刪除 try/catch 塊。 它們都沒有任何好處,而且它們會使您的代碼變得混亂 - 目前在您的方法主體中,您總共有 6 行“主體”代碼和 35 行毫無意義的 try/catch。 一旦你刪除了這些,你的GetCycleList
輔助方法也變得毫無意義變得更加明顯。 你可以只寫:
public override List<Cycle> RunReportListOut()
{
return Cycle.PatientForDateRange(this.CurrentPatient.PatientIDInternal,
this.StartDate, this.EndDate);
}
public override List<Cycle> RunReportListOut<Cycle>()
這將創建一個常規泛型方法,其類型參數恰好名為Cycle
它與public override List<T> RunReportListOut<T>()
沒有什么不同; type 參數仍然可以是任何類型。
你想要做的事情是完全不可能的; 你不能用非泛型方法覆蓋泛型方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.