将类型化的Func作为通用Func返回

时间:2011-06-27 16:04:32

标签: c# generics

我有多个数据源接口的实现。 它有一个方法CanGet用于发现它是否可以获取特定类型然后另一个Get用于执行它。 我试图编写这个特定的实现,但它确实喜欢从FindSource传回GetCostLedger,因为类型不匹配。我看不出如何让它发挥作用。 谢谢你的帮助。

private Func<IEnumerable<T>> FindSource<T>() where T : class
{
    if (typeof(CostLedger).IsAssignableFrom(typeof(T)))
        return GetCostLedger;

    if (typeof(EquipmentInventory).IsAssignableFrom(typeof(T)))
        return GetEquipmentInventory;

    if (typeof(ActivePavingJobs).IsAssignableFrom(typeof(T)))
        return GetActivePavingJobs;

    return null;
}

public IEnumerable<T> GetData<T>() where T : class
{
    var source = FindSource<T>();
    if (source != null)
        return source.Invoke();

    throw new NotImplementedException();
}

public bool CanGet<T>() where T : class
{
    return FindSource<T>() != null;
}

private IEnumerable<CostLedger> GetCostLedger()
{
    //Implementation clipped
}

private IEnumerable<EquipmentInventory> GetEquipmentInventory()
{
    //Implementation clipped
}

private IEnumerable<ActivePavingJobs> GetActivePavingJobs()
{
    //Implementation clipped
}

此代码的用例位于运行大量转换的ETL过程中 从工厂调用数据源,实现如此注入实现

_destination.SaveData(
    _mapper.Find<IEnumerable<CostLedger>, LaborAndEquipmentAnalysis>()
               .Process(_source.First(x => x.CanGet<CostLedger>())
    .GetData<CostLedger>(), dashboardName, DateTime.UtcNow));

2 个答案:

答案 0 :(得分:2)

为什么在此方法中使用开放泛型类型

private Func<IEnumerable<T>> FindSource<T>() where T : class {
    if (typeof(CostLedger).IsAssignableFrom(typeof(T)))
        return GetCostLedger;

    return null;
}

如果您要返回一个封闭的泛型类型?

也就是说,如果您在TT时实际使用T,那么为什么让这个方法适用于所有CostLedger CostLedger是引用类型? / p>

至少,如果你想要的只是private Func<IEnumerable<T>> FindSource<T>() where T : CostLedger 及其衍生类型,你应该说

private Func<IEnumerable<CostLedger>> FindSource()

但实际上,我不明白为什么你不只是说

T

如果CostLedger使用的只是{{1}}。

答案 1 :(得分:-1)

这肯定不是这样做的方法,但如果你必须......

private Func<IEnumerable<T>> FindSource<T>() where T : class
{
    if (typeof(CostLedger).IsAssignableFrom(typeof(T)))
        return ()=>GetCostLedger ().Cast<T> ();

    return null;
}