C#使用泛型调用重写的方法
我想我在这一点上有点困惑,但我似乎无法解决这个问题 我有一个接口C#使用泛型调用重写的方法,c#,generics,interface,overriding,C#,Generics,Interface,Overriding,我想我在这一点上有点困惑,但我似乎无法解决这个问题 我有一个接口ILinkHandler和4个其他处理程序类(从该接口继承)来验证链接的不同结构。在该接口中,我有一个taskvalidate()函数,用于验证链接并返回结果的Task>。根据T,我会在Validate()上返回不同的模型(我有4个不同的模型) 我的控制台应用程序执行以下操作。它调用任务Validate()方法,并在获得结果后创建一些日志(注意Validate()是async)。每个日志都有一点不同,因为模型不同,所以我重写了一个名
ILinkHandler
和4个其他处理程序类(从该接口继承)来验证链接的不同结构。在该接口中,我有一个taskvalidate()
函数,用于验证链接并返回结果的Task>。根据T
,我会在Validate()
上返回不同的模型(我有4个不同的模型)
我的控制台应用程序执行以下操作。它调用任务Validate()每个链接类型的code>方法,并在获得结果后创建一些日志(注意Validate()
是async
)。每个日志都有一点不同,因为模型不同,所以我重写了一个名为WriteResults(ModelX结果,字符串名称)
的方法,并且从ModelX类型(参见问题的结尾,我发布了两个示例)开始,我做了一些不同的事情(我认为在这个范围内并不重要,但如果必要,我可以提供详细信息)。此方法不是异步的
我想使用泛型和我的接口创建一个方法(ValidateModel
),该方法处理从模型类型对重写方法WriteResults
的正确调用,并从接口调用Validate()
方法
下面的代码是我所做的工作,但是if部分类似于我目前在main中所做的,我希望避免
public void ValidateModel<T>(ILinkHandler<T> handler, string name) where T : class
{
Console.WriteLine($"Validating {name}");
var results = handler.Validate();
if (typeof(T) == typeof(InternalLinksModel))
{
WriteResults(results.Result as List<InternalLinksModel>, name);
}
else // continue with other models
}
如果可能的话,我想要更多类似的东西,但这不能编译:
public void ValidateModel<T>(ILinkHandler<T> handler, string name) where T : class
{
Console.WriteLine($"Validating {name}");
var results = handler.Validate();
WriteResults<T>(results.Result as List<T>, name);
}
编辑:添加更多代码
接口:
public interface ILinkHandler<T>
{
Task<List<T>> Validate();
}
我最终重构了我所有的代码,看起来非常清晰。正如我所说,在一开始,我想我有点搞混了,这一切都是从我做出的一个糟糕的设计决定开始的
简而言之,我添加了一个新方法,WriteResults(字符串文件名)
。这样,我实现了该方法并从我的“Main”类中删除了重写的方法(writeResultsFripacksInCSV(列表结果,字符串文件名)
)。从那以后,我将接口中的Validate
方法签名更改为Task Validate()
,因为每个模型都有相同的签名,所以我删除了接口中的泛型。现在,我可以通过以下方式调用我的处理程序:
public void Validate(ILinkHandler handler, string filename)
{
Console.WriteLine($"Validating {filename}");
var results = handler.Validate();
SetUpResultsStatistics(results.Result, $"{filename}_Statistics");
handler.WriteResults(filename);
}
我创建了一个名为void SetUpResultsStatistics(List results,string filename)
的函数,该函数提供结果的统计信息,并且它对所有处理程序都是通用的(因此,为了避免重复,我将其放在那里)
代码现在更清晰了,它现在不使用任何泛型或重写方法。一、 然而,我仍然很好奇,我应该如何处理这样一个案例,并将尝试用一个更简单的例子在另一个问题中阐述它
谢谢大家的评论,非常感谢 您说您的Validate
方法是异步和返回模型,但在示例代码中,它们只是void
?ImageLinkHandler.Validate()代码>参数在哪里?您可以编辑您的帖子以包含WriteResults
的定义吗?很难说如何调用未显示的内容。@luisarcher您需要弄清楚什么是InternalLinksModel
,等等。WriterResult都有一个共同点,需要从它们那里获得。将其放入内部链接模型
等的接口中。所有这些都实现,然后传递IEnumerable
,而不是任何内容的列表。您可以将这些列表强制转换为IEnumerable。您不能将列表
强制转换为列表
,因为列表允许您添加项,并且您不能将基类实例添加到该类的子类列表中。你不需要也不想要那个列表。WriterResults所做的一切都是枚举,所以它只需要一个枚举。@luisarcher如果它们不都提供相同的东西,那么几乎可以肯定它们可以以相同的方式提供不同的东西。公共接口可以公开用于日志记录的名称/值对枚举,或者类似的内容。日志记录是一个很好的问题,因为不管怎样,它都会变成字符串
public interface ILinkHandler<T>
{
Task<List<T>> Validate();
}
public class InternalLinkHandler : ILinkHandler<InternalLinksModel>
{
public List<InternalLinksModel> InternalLinks = new List<InternalLinksModel>();
public async Task<List<InternalLinksModel>> Validate()
{
// Here set up my tests, call tasks that modifies InternalLinks List and I await for its results
return InternalLinks
}
public class XmlLinkCheckerValidator
{
// References to all modes
public ExternalLinkHandler ExternalLinkHandler => new ExternalLinkHandler();
public ImageLinkHandler ImageLinkHandler => new ImageLinkHandler();
public InternalLinkHandler InternalLinkHandler => new InternalLinkHandler();
public PdfLinkHandler PdfLinkHandler => new PdfLinkHandler();
public void ValidateIPack()
{
InitialSetup();
Console.WriteLine("Validating External_Links");
var resultsForExternalLinks = ExternalLinkHandler.Validate();
WriteResultsForIPacksInCsv(resultsForExternalLinks.Result, "External_Links");
Console.WriteLine("Validating Image_Links");
var resultsForImageLinks = ImageLinkHandler.Validate();
WriteResultsForIPacksInCsv(resultsForImageLinks.Result, "Image_Links");
Console.WriteLine("Validating Internal_Links");
var resultsForInternalLinks = InternalLinkHandler.Validate();
WriteResultsForIPacksInCsv(resultsForInternalLinks.Result, "Internal_Links");
// Console.WriteLine("Validating Pdf Links");
// var results = XmlLinkExtractorFromIPacks.PdfLinkHandler.Validate();
// WriteResultsForIPacks(results, "Pdf Links");
}
private void WriteResultsForIPacksInCsv(List<InternalLinksModel> results, string filename) { logging results }
private void WriteResultsForIPacksInCsv(List<ExternalLinksModel> results, string filename) { logging results }
private void WriteResultsForIPacksInCsv(List<ImageLinksModel> results, string filename) { logging results }
private void WriteResultsForIPacksInCsv(List<PdfLinksModel> results, string filename) { logging results }
private void WriteResultsForIPacksInCsv(List<InternalLinksModel> results, string filename) { logging results }
public void Validate(ILinkHandler handler, string filename)
{
Console.WriteLine($"Validating {filename}");
var results = handler.Validate();
SetUpResultsStatistics(results.Result, $"{filename}_Statistics");
handler.WriteResults(filename);
}