перегрузка синтаксического сахара c #

#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. Нет, мне не нужно абсолютное значение.