我怎么能在这里有一个通用方法?

时间:2016-09-27 09:03:43

标签: c# generics lambda

我有这些方法,您可能会认为我也可以使用其他数字类型。有什么方法可以将这些方法合并到一个通用方法中吗?

public long GetActiveDepartmentsQuotaOf ( Func<Department, long> exp )
{
    return Departments == null ? 0 : Departments.Where(d => d.Status == 1).Sum(exp);
}

public int GetActiveDepartmentsQuotaOf ( Func<Department, int> exp )
{
    return Departments == null ? 0 : Departments.Where(d => d.Status == 1).Sum(exp);
}

我试过了:

public T GetActiveDepartmentsQuotaOf<T> ( Func<Department, T> exp )
{
    return Departments == null ? 0 : Departments.Where(d => d.Status == 1).Sum(exp);
}

但语法错误。出现这种情况的方法是什么?我很好奇

2 个答案:

答案 0 :(得分:3)

这不起作用,因为Enumerable.Sum方法仅适用于可以概括的某些类型的IEnumebles(例如intdoublefloat)。< / p>

这是完整的重载列表:https://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum(v=vs.110).aspx

目前还不清楚如何总结IEnumerable<T>,其中T可以是任何东西。想象一下,例如TDepartment。你会期待什么.Sum()在那种情况下返回?

答案 1 :(得分:1)

这对你有用吗?

public T GetActiveDepartmentsQuotaOf<T>(Func<Department, double> exp)
    where T : IConvertible
{
    return (T)Convert.ChangeType(Departments == null
        ? 0 : Departments.Where(d => d.Status == 1).Sum(exp), typeof(T));
}

编辑:见最后

但是你必须将lambda(或方法)的返回值转换为int(如果你有一些十进制数,则为double)。

修改

如果您确实需要Func<Department, T>签名:

public T GetActiveDepartmentsQuotaOf<T>(Func<Department, T> exp)
    where T : IConvertible
{
    return (T)Convert.ChangeType(Departments == null
            ? 0
            : Departments.Where(d => d.Status == 1)
                .Sum(d => (int)Convert.ChangeType(exp(d), typeof(double)))
        , typeof(T));
}

编辑:我在我的解决方案中将类型从int更改为double(由于@Servy的注释),以确保没有人对支持小数的更改感到困惑。至少,现在,整数和小数也应该有效。 您还应该知道,使用小数时可能会导致精度损失(但我想只有长小数部分会受到影响)。