2016-09-27 3 views
1

У меня есть эти методы, и вы можете подумать, что я могу использовать его для других типов номеров. Есть ли способ, которым я могу объединить эти методы в один общий метод?Как я могу использовать общий метод здесь?

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

Это просто опечатка или вы пытались отделить 'T' от' TGetActiveDepartmentsQuotaOf'? –

+0

['Сам()' сам реализуется с несколькими перегрузками] (https://msdn.microsoft.com/en-us/library/bb548890 (v = vs.110) .aspx), как и ваши первые два метода. Нет интерфейса 'ISummable ' или 'IAddable ' (аналог «IEquatiable '), который вы можете использовать для ограничения 'T', и вы не можете сказать' где T: int или T: long или T: double' , Вы просто не можете добраться отсюда (кроме чем-то уродливого с отражением). Я не раз хотел, чтобы я мог. –

ответ

3

Это не будет работать, так как метод Enumerable.Sum работает только на IEnumerables определенных типов, которые могут быть подытожены (например int, double, float).

Вот полный список перегрузки: https://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum(v=vs.110).aspx

Неясно, как бы вы подвести итог в IEnumerable<T>, где T может быть что угодно. Представьте себе, например, что T - Department. Что бы вы ожидали .Sum(), чтобы вернуться в этом случае?

+0

Так что я искал ответ, как @Mong Zhu's. Условие ограничения использования определенных типов. Но он все равно дает ту же ошибку. Следовательно, у меня нет большого количества вариантов, либо используйте многие методы, либо принимайте преобразование, как предлагает romain-aga. –

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

Edit: Смотрите в конце

Но вам придется преобразовать в целое (или двойной, если вы можете иметь несколько десятичных чисел) возвращаемое значение вашей лямбды (или метод).


EDIT

Если вам действительно нужно 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)); 
} 

Edit: Я изменил тип с междунар удвоится в моем решении (из-за замечанием @ Servy в), чтобы никто не запутался в изменении, чтобы сделать его десятичной. По крайней мере, теперь целые и десятичные числа должны работать. Вы также должны знать, что при использовании десятичных знаков вы можете потерять точность, но я думаю, что на нее повлияет только длинная десятичная часть.

+0

Это не собирается вычислять правильную сумму для нецелых значений, что еще хуже, она не дает никаких указаний на это; подпись будет означать, что она будет правильно суммировать любой конвертируемый тип, даже если он не может. – Servy

+0

Вот почему я сказал, что он может измениться до двух, если ему нужно вычислить некоторые десятичные числа;) Но я знаю, что решение, которое я написал, не работает с десятичными знаками.Поскольку вы сказали это, я поменяю типы, по крайней мере, больше не может быть путаницы. –

+0

Не имеет значения, какой из них вы выбираете, суть в том, что вы можете поддерживать только один тип *, а не * все * из них. Если вы измените его на использование суммарных сумм на двойные суммы, он не будет работать для недвойных сумм. Если вы измените его на использование десятичных знаков, то он не будет работать для не десятичных сумм. Вы должны фактически использовать сумму, основанную на самом фактическом типе, чтобы надежно получить правильный результат. – Servy

Смежные вопросы