Tolga Evcimen
Tolga Evcimen

Reputation: 7352

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

Upvotes: 1

Views: 83

Answers (2)

romain-aga
romain-aga

Reputation: 1561

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).

Upvotes: 1

Cristian Lupascu
Cristian Lupascu

Reputation: 40506

This will not work, because the Enumerable.Sum method only works on IEnumerables of certain types which can be summed up (e.g. 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?

Upvotes: 3

Related Questions