Другие упоминали IEquatable<T>
, что, безусловно, является хорошим потенциальным ограничением.
Другая опция, которую нужно запомнить, - EqualityComparer<T>.Default
, которая будет использовать IEquatable<T>
, если она доступна, но в противном случае вернется к object.Equals(object)
. Это означает, что вы можете использовать его с типами, которые предшествуют шаблонам, но переопределяют Equals
, например:
bool IsInList<T>(T value, params T[] args)
{
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
bool found = false;
foreach(var arg in args)
{
if(comparer.Equals(arg, value))
{
found = true;
break;
}
}
return found;
}
Обратите внимание, что компаратор равенства по умолчанию также справляется с нулевыми ссылками, поэтому вам не нужно беспокоиться о них самостоятельно. Если тип T
не переопределил object.Equals(object)
или не реализовал IEquatable<T>
, вы получите семантику равенства ссылок (т.е. он вернет true
только если точная ссылка находится в массиве).
Несколько других моментов:
Ваше желание придерживаться единой точки выхода делает код менее читабельным, ИМО. Здесь нет необходимости в дополнительной переменной:
bool IsInList<T>(T value, params T[] args)
{
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
foreach (var arg in args)
{
if (comparer.Equals(arg, value))
{
return true;
}
}
return false;
}
LINQ уже содержит метод для этого Contains
, поэтому вы можете упростить код до:
bool IsInList<T>(T value, params T[] args)
{
return args.Contains(value);
}
Array
также эффективно содержит эту функцию, с IndexOf
:
bool IsInList<T>(T value, params T[] args)
{
return Array.IndexOf(args, value) != -1;
}
1036 **
Ваш метод, возможно, несколько неверно назван, учитывая, что args
- это массив, а не List<T>
.