#c# #generics #operator-overloading
#c# #обобщения #перегрузка оператора
Вопрос:
У меня есть следующий метод:
virtual public int nonNeg(int? numIn)
{
if ((numIn < 0) || (numIn ==null))
{
return 0;
}
else return (int)numIn;
}
Я хочу иметь возможность использовать единый метод, который мог бы принимать либо байты, либо короткие значения, либо целые числа, чтобы преобразовать эти значения в неотрицательное число. Как я мог этого добиться?
Комментарии:
1. Является ли производительность проблемой здесь или нет?
2. Я смущен вопросом. Байты уже неотрицательны, так зачем вам что-то с ними делать?
Ответ №1:
Обычно я бы не стал предлагать это, но, на мой взгляд, следующие перегрузки должны охватывать большинство ваших случаев. Они будут охватывать типы с нулевым значением и ненулевые типы, компилятор выберет соответствующую перегрузку.
public static T nonNeg<T>(T n) where T : struct, IComparable
{
if (n.CompareTo(default(T)) <= 0)
{
return default(T);
}
return n;
}
public static T nonNeg<T>(T? n) where T : struct, IComparable
{
if (!n.HasValue || n.Value.CompareTo(default(T)) <= 0)
{
return default(T);
}
return n.Value;
}
Ответ №2:
Или просто используйте Math.Max( 0, numIn)
Комментарии:
1. Может быть, там есть GetValueOrDefault()?
Ответ №3:
Возможно, что-то вроде этого (проверено):
virtual public T nonNeg<T>(T numIn) where T : IComparable<T>
{
if (numIn==null){
return default(T);
}
if (Comparer<T>.Default.Compare(numIn,default(T))<0)
{
return default(T);
}
else
return (T)numIn;
}
Комментарии:
1. Проблема здесь заключается в обратном приведении к int для сравнения. Вы должны добавить «where T: struct», чтобы подпись была действительной, и преобразовать любую структуру в целочисленный тип не так просто. Самый простой способ на самом деле — выполнять перегрузки, или использовать библиотечные функции, как предлагают другие, или привести вызывающий объект к int ?.
2. Это не сработает. Вы не можете использовать
<
против общего параметра.3. Я столкнулся с той же проблемой, что и CMP, предложенный. Я хотел бы, чтобы приведенный выше код был изменен и протестирован, чтобы сделать код более элегантным в моем проекте, поскольку использование Math.Max не обрабатывает типы с нулевым значением
4. 1) ограничьте метод, чтобы он был
where T : struct
. 2) Сравните, используя( Comparer<T>.Default.Compare ( numIn.Value, default ( T ) ) < 0 )
и 3) верните значение по умолчанию (T) вместо 0.
Ответ №4:
Я думаю, вы можете сделать это с:
int negativeNumber = -22;
int nonNegativeNumber = Math.Abs(negativeNumber);
результатом будет 22
или
decimal negativeNumber = -22.2;
decimal nonNegativeNumber = Math.Abs(negativeNumber);
результат будет 22.2
Комментарии:
1. Нет, мне не нужно абсолютное значение.