简体   繁体   中英

How can I have a Generic method here?

I have these methods, and you may think I may have it for the other number types too. Is there any way that I may merge these methods into one generic method?

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);
}

I tried this:

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

But it wrong syntactically. What is the way out of this situation? I am just curious

This will not work, because the Enumerable.Sum method only works on IEnumerables of certain types which can be summed up (eg int , double , float ).

Here's the full overload list: https://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum(v=vs.110).aspx

It is unclear how you would sum up an IEnumerable<T> , where T can be anything. Imagine, for example that T is Department . What would you expect .Sum() to return in that case?

Does this work for you ?

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));
}

Edit: See at the end

But you will have to convert to int (or a double if you can have some decimal numbers) the return value of your lambda (or method).


EDIT

If you really need the Func<Department, T> signature:

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));
}

Edit: I changed the type from int to double in my solution (due to the @Servy's comment), to be sure no one get confused by the change to make to support decimal. At least, now, integers and decimals should work either. You should also be aware, you can get a loss of precision when using decimals (but I guess only a long decimal part would be affected).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM