返回从任务的泛型约束派生的类

时间:2017-09-12 17:20:02

标签: c# user-interface generics async-await

我创建了一个通用任务接口

public interface ICalcLoaderTask
{   
    Task<T> Execute<T>(BaseTaskParameters taskParams, CancellationToken cancellationToken) where T : CalcLoaderTaskResult;
}

从CalcLoaderTaskResult派生的类

public class CopyNMStoreResult : CalcLoaderTaskResult
{
    public string NMStoreResultsFilePath { get; set; }
}

在我的ICalcLoaderClass实现中,我找不到返回结果类的方法

public async Task<T> Execute<T>(BaseTaskParameters taskParams, CancellationToken cancellationToken) where T : CalcLoaderTaskResult
    {
        var copyFileTaskParams = (CopyFilesTaskParameters)taskParams;
        var GlobalNMStoreResultsFilePath = string.Format("{0}\\WhateverTheFileNameIs.xls", copyFileTaskParams.GlobalShareFolderPath);
        var LocalNMStoreResultsFilePath = string.Format("{0}\\WhateverTheFileNameIs.xls", copyFileTaskParams.GlobalShareFolderPath);

        await FileUtility.CopyFileAsync(GlobalNMStoreResultsFilePath, LocalNMStoreResultsFilePath, cancellationToken);

        var result = new CopyNMStoreResult
        {
            NMStoreResultsFilePath = GlobalNMStoreResultsFilePath
        };
        return result; //Cannot implicitly convert type
    }

如何归还此结果?或者我的模式不正确?我将重新使用这种类型的模式,其中包含从CalcLoaderTaskResult派生的不同返回类型。 CalcLoaderTaskResult是抽象的

1 个答案:

答案 0 :(得分:2)

由于您的实现总是返回相同类型的对象,因此我将以不同的方式制定接口

public interface ICalcLoaderTask<T>
    where T : CalcLoaderTaskResult
{   
    Task<T> Execute(BaseTaskParameters taskParams, CancellationToken cancellationToken)
}

即。类型(接口)是通用的而不是方法。

然后让您的实现实现具体类型

public class MyImplementation : ICalcLoaderTask<CopyNMStoreResult>
{
    public async Task<CopyNMStoreResult> Execute(BaseTaskParameters taskParams,
                                                 CancellationToken cancellationToken)
    {
        ...
        var result = new CopyNMStoreResult
        {
            NMStoreResultsFilePath = GlobalNMStoreResultsFilePath
        };
        return result;
    }
}

因为调用者无论如何都无法选择返回值的类型。

技术上可以让泛型类型参数打开

public class MyImplementation<T> : ICalcLoaderTask<T> where T ...

但由于您的方法的返回类型是硬编码的,因此没有任何优势。

注意:可以让方法返回不同的类型。添加泛型类型约束new允许您使用new T()创建对象。约束new表示类型T必须具有默认构造函数。

T MyMethod<T>()
    where T : MyBase, new
{
    return new T();
}