Правильно ли я понимаю этот фрагмент кода?
Я рассматриваю код от одного из наших подрядчиков:
if (userLists != null)
{
Int32 numberOfItems = userLists.Count;
if ((numberOfItems & 1) == 1)
{
var emptyList = new tblList();
userLists.Add(emptyList);
}
}
Теперь я пытаюсь понять это, так что, может, кто-нибудь подтвердит со мной, правильно я понял или нет?
- Есть ли у нас экземпляр userList?
- Да. Получить количество элементов в объекте userLists.
- если (количество элементов равно 1 (Да / истина) И 1 равно 1 (да / Истина)) И этот результат равен 1 (Да / Истина), тогда добавьте пустой список в список.
- Остальное: ничего
Если это так (WTFFFFFFFFFFFFFFFFFFFF!!!!!!!!!!), это может быть изменено на
if (numberOfItems == 1)
{
..
}
но даже это дерьмо, потому что я не хочу список с "пустыми" элементами.
Так я правильно прочитал этот кусок кода?
О, еще один вздох при использовании Int32
против Int
:( (но я отвлекся).
9 ответов
&
это то, что называется побитовым оператором. В то время как оператор &&
проверяет два логических значения:
TRUE && FALSE => FALSE
TRUE && TRUE => TRUE
&
Оператор может работать с целочисленными значениями:
00101101 (45)
& 01011011 (91)
---------------
= 00001001 (9)
Для каждого бита выполняется логическая операция (и). Так что в случае с вашим примером кода он спрашивает: "Является ли последний бит 1?" - то есть "это странно?" Например, если число равно 23:
00010111 (23)
& 00000001 (1)
---------------
= 00000001 (1)
Так что это добавляет в список, потому что 1 == 1. Но если число было 22:
00010110 (22)
& 00000001 (1)
---------------
= 00000000 (0)
Так что это не добавляет в список.
Побитовое И-число с 1 проверяет, является ли число нечетным или четным (возвращает 1, если нечетное). Этот код делает, чтобы убедиться, что список имеет четное количество элементов, добавив еще один элемент, если есть нечетное количество элементов.
Так как мы глупые...
public static class Extensions
{
public static bool IsEven(this Int32 integer)
{
return (integer % 2 == 0);
}
}
Давай сделаем...
numberOfItems.IsEven()
Проверка на нечетность, можно также сделать i % 2 != 0
Я бы посоветовал посмотреть на битовые маски, они могут быть очень удобными, но не в коде, который вы задали, я бы предпочел модульную, если вам нужно сделать четные / нечетные.
static void Main(string[] args)
{
for (int i = 0; i < 100; i++ )
Console.WriteLine( i & 1);
Console.ReadLine();
}
1
0
1
0
1
0
И, черт возьми, вот некоторые методы расширения
class Program
{
static void Main(string[] args)
{
List<int> ints = new List<int>();
for (int i = 0; i < 100; i++)
{
Console.WriteLine("Mod: {0}", i % 2 );
Console.WriteLine("BitWise: {0}", i & 1 );
ints.Add(i);
Console.WriteLine("Extension: {0}", ints.IsEven() );
}
Console.ReadLine();
}
}
public static class ListExtensions
{
public static bool IsEven<T>(this ICollection<T> collection)
{
return (collection.Count%2) == 0;
}
public static bool IsOdd<T>(this ICollection<T> collection)
{
return (collection.Count%2) != 0;
}
}
Ноль элементов в порядке?
x = (0 & 1) тогда (x == 1) ложно...
Я думаю, что вы должны попросить ваших подрядчиков прокомментировать их код больше.
Может быть переработан, чтобы быть более понятным / поддерживаемым:
if (userLists != null)
{
EnsureListHasAnEvenNumberOfItems(userLists);
}
Для (numberOfItems &1)==1 это побитовое AND. Кажется, что он проверяет, является ли numberOfItems нечетным, и добавляет пустой список, если это так.
((numberOfItems & 1) == 1)
& с 1 тестами 0 бит. Для целочисленных типов данных для всех нечетных значений установлен 0-й бит, а для всех четных значений он очищен. Приведенный выше код эффективно проверяет наличие нечетного значения.