#c# #generics
#c# #дженерики
Вопрос:
private delegate T MyFunc<T>(int i);
private static double SumNumber(int i, int n, MyFunc<double> func)
{
double sum = 0.0;
for (int j = i; i <= n; j )
{
sum = func(j);
}
return sum;
}
private static Vector SumVector(int i, int n, MyFunc<Vector> func)
{
Vector sum = new Vector(0.0, 0.0);
for (int j = i; i <= n; j )
{
sum = func(j);
}
return sum;
}
Это программа для вычисления суммы myFunc(j), где j — от i до n .
Я попытался использовать интерфейс, подобный:
interface IAddable<T>
{
static T operator (T x, T y);
}
но это не сработало.
Итак, что мне делать?
Комментарии:
1. вы могли бы использовать Func вместо myFunc таким образом, вам не пришлось бы создавать делегат и использовать тот, который есть в .net
Ответ №1:
Во-первых, обратите внимание, что во многих отношениях нестандартная версия перегрузки проще. Универсальные типы не поддерживают ни операторы, ни интерфейсы.
Действительно, если Sum
для ваших типов доступны методы (возможно, с помощью методов расширения IEnumerable<T>
), вызывающий может использовать просто:
var data = sourceData.Select(projection).Sum();
где projection
моральный эквивалент func
.
Для того, чтобы сделать это по-своему, то, что вы могли бы попробовать в первую очередь, это dynamic
:
private static T Sum<T>(int i, int n, Func<int,T> func)
{
if(i >= n) throw new ArgumentOutOfRangeException();
T sum = func(i);
for (int j = i 1; i <= n; j )
{
sum = (dynamic)sum (dynamic)func(j);
}
return sum;
}
в противном случае, есть некоторые хитрости, которые вы можете сделать, чтобы подделать универсальные операторы (см. MiscUtil ), или вы можете передать метод accumulator (т.Е. Func<T,T,T> add
) в качестве параметра.
Комментарии:
1. @Jon побил меня в поиске ссылки MiscUtil; p
2. Может ли объект
dynamic
типа быть неявно преобразован в объект типаT
? Я имею в виду, не следует ли вам написать это вместо :sum = (T)((dynamic)sum (dynamic)func(j));
3. @Nawaz
dynamic
может быть неявно преобразован во что угодно , но обратите внимание, что проверка выполняется во время выполнения; там есть большое предположение: что существует определенный оператор(T,T)
, который возвращаетT
.4. @MarcGravell: Я собирался опубликовать довольно похожий ответ, так что он у меня был готов 🙂
5. @Nawaz ваше
(T)
добавление тоже имеет смысл и, возможно, проясняет намерение; результат тот же, и я, конечно, не был бы против того, чтобы(T)
там было больше.