Перегрузка оператора дженериками
Возможный дубликат:
Перегрузка арифметического оператора для общего класса в С#
Вот код для генерического класса i, который был создан для добавления сложного числа для перегрузки оператора.
public class Complex<T>
{
public T _a, _b;
public Complex(T i, T j)
{
_a = i;
_b = j;
}
public static Complex<T> operator +(Complex<T> i, Complex<T> j)
{
return new Complex<T>(i._a + j._a, i._b + j._b);
}
}
во время работы с этим я получил ошибку,
Error: Operator '+' cannot be applied to operands of type 'T' and 'T'
Может ли кто-нибудь предложить мне, как я могу использовать перегрузку оператора с помощью дженериков?
Ответы
Ответ 1
Проблема заключается в том, что компилятор не может знать, можно ли применить оператор +
к T
. К сожалению, нет способа ограничить T
числовым типом в С#.
Однако вы можете обходным путем использовать динамическое время выполнения:
public class Complex<T> where T : struct
{
public T _a, _b;
public Complex(T i, T j)
{
_a = i;
_b = j;
}
public static Complex<T> operator +(Complex<T> i, Complex<T> j)
{
return new Complex<T>(Sum(i._a, j._a), Sum(i._b, j._b));
}
private static T Sum(T a, T b)
{
return (dynamic)a + (dynamic)b;
}
}
Ответ 2
Если вы хотите обмануть, вы можете временно пометить их как тип dynamic
и позволить среде выполнения определять, как это сделать. Пока тип T
, который вы используете, определяет оператор +
, он будет работать. Это означает, что он будет работать как для чисел, так и для строк, или любого другого типа (пользовательский или другой); не уверен, что это ваше намерение для Complex
или нет. Кроме того, если нет оператора +
для использования, исключение будет выдаваться во время выполнения; нет способа (что я знаю), чтобы выполнить проверку времени компиляции.
public class Complex<T>
{
public T _a, _b;
public Complex(T i, T j)
{
_a = i;
_b = j;
}
public static Complex<T> operator +(Complex<T> i, Complex<T> j)
{
dynamic d_i = i;
dynamic d_j = j;
return new Complex<T>(d_i._a + d_j._a, d_i._b + d_j._b);
}
}
Использование примера со строками:
Complex<string> i = new Complex<string>("Hel", "Wor");
Complex<string> j = new Complex<string>("lo ", "ld!");
Complex<string> ij = i + j;
Console.WriteLine(ij._a + ij._b); //Hello World!
Ответ 3
Вы не можете суммировать два типа общих объектов; в статической функции вы пытаетесь добавить два элемента типа T i._a и j._a., но T может быть любого типа
что вы пытаетесь сделать?
Ответ 4
Как упоминалось выше, вы можете ограничить T
как IConvertible
, а затем использовать тип decimal
для выполнения требуемой математической функции следующим образом:
public class Complex<T> where T : struct, IConvertible
{
public T _a, _b;
public Complex(T i, T j)
{
_a = i;
_b = j;
}
public static Complex<T> operator +(Complex<T> i, Complex<T> j)
{
return new Complex<T>(Sum(i._a, j._a), Sum(i._b, j._b));
}
private static T Sum(T a, T b)
{
return (T)Convert.ChangeType(a.ToDecimal(CultureInfo.CurrentCulture) + b.ToDecimal(CultureInfo.CurrentCulture), typeof(T));
}
}