Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用泛型调用重写的方法_C#_Generics_Interface_Overriding - Fatal编程技术网

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()方法,并在获得结果后创建一些日志(注意
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);
}