开发者

Returning a typed Func as a generic Func

开发者 https://www.devze.com 2023-03-16 03:49 出处:网络
I have multiple implementations of a data source interface. It has on开发者_运维问答e method CanGet used to discover if it can source a particular type and then another Get used to execute it.

I have multiple implementations of a data source interface. It has on开发者_运维问答e method CanGet used to discover if it can source a particular type and then another Get used to execute it. I am trying to code this specific implementation as such but it does like passing GetCostLedger back from the FindSource because the types do no not match. I can not see how to get this to work. Thanks for any help.

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
}

The use case for this code is in an ETL process that runs a lot of transformations The data sources are called from a factory with the implementations injected like so

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


Why are you using an open generic type in this method

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

    return null;
}

if you are returning a closed generic type?

That is, why are you letting this method work for all T where T is a reference type if you are actually using it when T is CostLedger?

At a minimum, if all you ever want is CostLedger and its derived types, you should say

private Func<IEnumerable<T>> FindSource<T>() where T : CostLedger

But really, I don't see why you don't just say

private Func<IEnumerable<CostLedger>> FindSource()

if all you are using for T is CostLedger.


This is most certainly not the way to do it, but if you must....

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

    return null;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消