Сравнение Generic
От: e.thrash  
Дата: 05.04.16 07:02
Оценка:
Есть такой код

 class Checker  
    {
        public bool Check<T>(T item) where T : IComparable<T>
        {
            return item.CompareTo(0) < 0;
        }        
    }



как сделать сравнение с нулем? на входе могут быть int, decimal
Re: Сравнение Generic
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.04.16 07:16
Оценка:
Здравствуйте, e.thrash, Вы писали:


ET>как сделать сравнение с нулем? на входе могут быть int, decimal

Convert.ChangeType

class Checker  
    {
        public bool Check<T>(T item) where T : IComparable<T>
        {
            return item.CompareTo(Convert.ChangeType(0,typeof(T)) < 0;
        }        
    }


Вот пример для перечислений

 var парам = параметры[0];
            var тип = парам.GetType();

            long res = (long)Convert.ChangeType(парам, typeof(long));

            for (int i = 1; i < параметры.Length; i++)
                res |= (long)Convert.ChangeType(параметры[i], typeof(long));


            if (тип.IsEnum)
            {
                var ТипЗначений = Enum.GetUnderlyingType(тип);
                var number = Convert.ChangeType(res, ТипЗначений);
                return AutoWrap.ОбернутьОбъект(Enum.ToObject(тип, number));
            }
и солнце б утром не вставало, когда бы не было меня
Re: Сравнение Generic
От: Berill Азербайджан  
Дата: 05.04.16 07:29
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Есть такой код


ET>
ET> class Checker  
ET>    {
ET>        public bool Check<T>(T item) where T : IComparable<T>
ET>        {
ET>            return item.CompareTo(0) < 0;
ET>        }        
ET>    }
ET>



ET>как сделать сравнение с нулем? на входе могут быть int, decimal


Может так?
class Checker
    {
        public static int CompareWithZero<T>(T toCompare) where T : IComparable
        {
            if (toCompare is int)
            {
                return toCompare.CompareTo(0);
            }
            
            if (toCompare is decimal)
            {
                return toCompare.CompareTo(0m);
            }
            
            throw new ArgumentException("Параметр должен иметь тип int или decimal");
        }
    }
Re[2]: Сравнение Generic
От: Berill Азербайджан  
Дата: 05.04.16 07:58
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, e.thrash, Вы писали:



ET>>как сделать сравнение с нулем? на входе могут быть int, decimal

S>Convert.ChangeType

S>
S>class Checker  
S>    {
S>        public bool Check<T>(T item) where T : IComparable<T>
S>        {
S>            return item.CompareTo(Convert.ChangeType(0,typeof(T)) < 0;
S>        }        
S>    }
S>


Не скомпилится.
Надо:
item.CompareTo((T)Convert.ChangeType(0, typeof(T)))
Отредактировано 05.04.2016 7:59 Berill . Предыдущая версия .
Re[2]: Сравнение Generic
От: e.thrash  
Дата: 05.04.16 08:22
Оценка:
Здравствуйте, Berill, Вы писали:

B>Здравствуйте, e.thrash, Вы писали:


ET>>Есть такой код


ET>>
ET>> class Checker  
ET>>    {
ET>>        public bool Check<T>(T item) where T : IComparable<T>
ET>>        {
ET>>            return item.CompareTo(0) < 0;
ET>>        }        
ET>>    }
ET>>



ET>>как сделать сравнение с нулем? на входе могут быть int, decimal


B>Может так?

B>
class Checker
B>    {
B>        public static int CompareWithZero<T>(T toCompare) where T : IComparable
B>        {
B>            if (toCompare is int)
B>            {
B>                return toCompare.CompareTo(0);
B>            }
            
B>            if (toCompare is decimal)
B>            {
B>                return toCompare.CompareTo(0m);
B>            }
            
B>            throw new ArgumentException("Параметр должен иметь тип int или decimal");
B>        }
B>    }


а как теперь его использовать внутри класса Checker?

class Checker<T> 
{
   public T CheckValue { get; set; }
   public String CheckValueStr 
  {
   get 
    {
    return CompareWithZero(CheckValue) > 0 ? "" : "-";
    }
   }

    public int CompareWithZero<T>(T toCompare) where T : IComparable
        {
            if (toCompare is int)
            {
                return toCompare.CompareTo(0);
            }
            
            if (toCompare is decimal)
            {
                return toCompare.CompareTo(0m);
            }
            
            throw new ArgumentException("Параметр должен иметь тип int или decimal");
        }
}
Отредактировано 05.04.2016 20:19 VladD2 . Предыдущая версия .
Re: Сравнение Generic
От: vorona  
Дата: 05.04.16 08:31
Оценка: +4
Здравствуйте, e.thrash, Вы писали:

return item.CompareTo(default(T)) < 0;
Re: Сравнение Generic
От: ksg71 Германия  
Дата: 05.04.16 09:14
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Есть такой код


ET>
ET> class Checker  
ET>    {
ET>        public bool Check<T>(T item) where T : IComparable<T>
ET>        {
ET>            return item.CompareTo(0) < 0;
ET>        }        
ET>    }
ET>



ET>как сделать сравнение с нулем? на входе могут быть int, decimal


ну и оставьте decimal к нему интегральные типы неявно приводятся, или обязательно generic?
добавьте еще double и сравнивайте все числа

class Checker
        {
            public bool Check(decimal item)
            {
                return item.CompareTo(0) < 0;
            }

            public bool Check(double item)
            {
                return item.CompareTo(0.0) < 0;
            }
        }
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re: Сравнение Generic
От: xy012111  
Дата: 05.04.16 10:33
Оценка: +1
Здравствуйте, e.thrash, Вы писали:

ET>Есть такой код

ET> class Checker  
ET>    {
ET>        public bool Check<T>(T item) where T : IComparable<T>
ET>        {
ET>            return item.CompareTo(0) < 0;
ET>        }        
ET>    }

ET>как сделать сравнение с нулем? на входе могут быть int, decimal

Ещё бы неплохо или добавить ограничение struct:
where T : struct, IComparable<T>

или какую-нибудь проверку на null в коде.
Re[2]: Сравнение Generic
От: Sinix  
Дата: 05.04.16 11:46
Оценка: +5
Здравствуйте, Serginio1, Вы писали:

S>Convert.ChangeType


Убивать за такое в продакшн-коде надо, такая закладка не ловится почти никогда. А выстреливает, например, вот так.

Правильный ответ:
  return Comparer<T>.Default.Compare(item, default(T));

Но вообще вопрос осень странный, с сценария начинать надо. А то для SqlInt32 или для Nullable<>, скажем, сюрпрайз будет.
И вообще может оказаться, что простого EqualityComparer<T> хватит.
Отредактировано 05.04.2016 11:48 Sinix . Предыдущая версия .
Re[3]: Сравнение Generic
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.04.16 12:52
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>Convert.ChangeType


S>Убивать за такое в продакшн-коде надо, такая закладка не ловится почти никогда. А выстреливает, например, вот так.


Уже умер
Сейчас переношу данные из 1С 7.7 в 8.3
и солнце б утром не вставало, когда бы не было меня
Отредактировано 05.04.2016 12:53 Serginio1 . Предыдущая версия .
Re: Сравнение Generic
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.04.16 20:37
Оценка: 1 (1)
Здравствуйте, e.thrash, Вы писали:

ET>как сделать сравнение с нулем? на входе могут быть int, decimal


Общий подход, который можно тут применять, таков:
using System;

interface IChecker<T>
{
  bool Check(T item);
}

class Checker : IChecker<int>, IChecker<decimal> // можно реализовывать и в разных классах
{
  public bool Check(decimal item)
  {
    return item < 0;
  }

  public bool Check(int item)
  {
    return item < 0;
  }
}

class Checker<T>
{
  public static IChecker<T> Instance;
}

class Program
{
  static void Test<T>(T item)
  {
    if (Checker<T>.Instance.Check(item))
      Console.WriteLine("OK");
    else
      Console.WriteLine("Fail");
  }

  static void Main()
  {
    Checker<int>.Instance = new Checker();
    Checker<decimal>.Instance = new Checker();

    Test(-1);
    Test(42);
    Test(-0.42m);
  }
}


Если IChecker<T> Instance не присвоить реализацию нужного типа, будет (ожидаемо) NRE.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Отредактировано 07.04.2016 11:52 VladD2 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.