Побитовое ИЛИ для определения SqlBulkCopyOptions?

bitwise-or c# sqlbulkcopy

Вопрос

Поэтому я попросил одного из моих старших разработчиков помочь выяснить причину проблемы с транзакцией, и он подошел к моему столу и использовал другую перегрузку на SqlBulkCopy, а для параметра SqlBulkCopyOptions он сделал что-то вроде ниже:

SqlBulkCopyOptions options = (SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints);

Он работает сейчас, но я не понимаю, что по- bitwise or означает здесь. Я думал, что у меня есть некоторое понимание этого, никогда не использовал его, но это использование заставило меня почесать голову. Да, я не просил моего старшего объяснить это мне. Я надеялся, что кто-то может помочь мне понять, что говорится в заявлении. Большинство побитовых или примеров в сети с некоторыми номерами, которые я получаю (я думаю), но это?

Принятый ответ

Перечисление может использоваться в качестве флага, если оно имеет атрибут [Flags] и имеет значения перечисления, которые не зависят друг от друга:

Определение SqlBulkCopyOptions приведено здесь: https://github.com/Microsoft/referencesource/blob/master/System.Data/System/Data/SqlClient/SqlBulkCopyOptions.cs

Игнорируйте использование синтаксиса битдвига. Фактические значения:

Name              Hex  Dec  Pow 2   Binary
Default          =  0 =  0 =    0 = 00000000
KeepIdentity     =  1 =  1 =    1 = 00000001
CheckConstraints =  2 =  2 =    2 = 00000010
TableLock        =  4 =  4 =    3 = 00000100
KeepNulls        =  8 =  8 =    4 = 00001000
FireTriggers     = 10 = 16 =    5 = 00010000
UseInternalTxn   = 20 = 32 =    6 = 00100000

Обратите внимание, что каждое значение является следующей мощностью 2, что означает, что в двоичном (последний столбец) их биты полностью взаимоисключающие.

Это означает, что вы можете комбинировать их таким образом, чтобы вы могли видеть, что каждое значение задано, например, если вы хотите KeepIdentity и TableLock , это 0x01 с 0x04 . Мы используем оператор OR, но на основе бит, который дает нам поведение, которое мы хотим:

В двоичном формате:

00000001
00000100 OR
--------
00000101

Обратите внимание, как первый и третий бит теперь 1 .

Таким образом, ( KeepIdentity | TableLock == 5 ).

Этот подход не работает для значений перечисления, которые не являются значениями двух, например, если значение KeepIdentity имеет значение 1 а значение CheckConstraints имеет значение 2 но TableLock имеет значение 3 , а затем в двоичном TableLock они:

00000001 KeepIdentity
00000010 CheckConstraints
00000011 TableLock

Обратите внимание, что, анализируя биты 00000011 невозможно определить, является ли это комбинацией KeepIdentity и CheckConstraints или одного значения TableLock . Вот почему значения перечислений флагов должны быть: 1. Полномочия 2 и 2: взаимоисключающие (с исключениями для сокращенных и комбинированных значений).


Популярные ответы

Принцип в точности совпадает с enum как с числами, так как основной тип enum всегда является интегральным типом. Если вы посмотрите на объявление SqlBulkCopyOptions , вы увидите, что его члены имеют базовые значения, которые имеют две степени, чтобы они могли быть объединены таким образом.



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow