Подтвердить что ты не робот

Преобразование выражения bool в char в С#

Я передал .NET-викторину, когда встретил вопрос вроде ниже.

Char ch = Convert.ToChar('a' | 'e' | 'c' | 'a');

В консоли мы видим, что вывод для переменной ch равен g.

Может кто-нибудь описать, что происходит? Спасибо!

4b9b3361

Ответ 1

Это не то, что кажется на первом месте. Это больше бинарных вычислений в представлении int этих Char:

Вот полная статья, объясняющая это примерами: Article

Таким образом, двоичный результат для побитового Or этих 'a' | 'e' | 'c' | 'a' равен 103. Если вы преобразуете это значение в Char, это g

Edit:

Я вижу, что этот ответ занял больше внимания, чем я, хотя он заслуживает более подробной информации.

С С# Компилятор:

Существует неявное преобразование из char в int (int i = 'a' компиляции), поэтому на самом деле компилятор:

Convert.ToChar((int)'a' | (int)'e' | (int)'c' | (int)'a');

Поскольку это жестко закодированные значения, компилятор делает больше работы:

Convert.ToChar(97 | 101 | 99 | 97);

и, наконец:

Convert.ToChar(103); // g

Если это не были жестко заданные значения:

private static char BitwiseOr(char c1, char c2, char c3, char c4)
{
    return Convert.ToChar(c1 | c2 | c3 | c4);
}

Используя Roslyn, вы получаете:

private static char BitwiseOr(char c1, char c2, char c3, char c4)
{
    return Convert.ToChar((int)c1 | c2 | c3 | c4);
}

Преобразован в IL (Or (побитовое) использование команды IL):

.method private hidebysig static char  BitwiseOr(char c1,
                                                   char c2,
                                                   char c3,
                                                   char c4) cil managed
  {
    // 
    .maxstack  2
    .locals init (char V_0)
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  ldarg.1
    IL_0003:  or
    IL_0004:  ldarg.2
    IL_0005:  or
    IL_0006:  ldarg.3
    IL_0007:  or
    IL_0008:  call       char [mscorlib]System.Convert::ToChar(int32)
    IL_000d:  stloc.0
    IL_000e:  br.s       IL_0010

    IL_0010:  ldloc.0
    IL_0011:  ret
  } // end of method Program::BitwiseOr

Ответ 2

"|" является двоичным оператором OR.

'a' binary representation is 01100001
'e' binary representation is 01100101
'c' binary representation is 01100011

Результатом OR является 01100111, представление char g

Ответ 3

Перейдите в unicode-table.

  • 'a' Десятичное значение 97 в двоичном формате 01100001.
  • 'e' Десятичное значение 101 в двоичном формате 01100101.
  • 'c' Десятичное значение 99 в двоичном формате 01100011.
  • 'a' Десятичное значение 97 в двоичном формате 01100001.
Оператор

или по биту имеет значение '|'. Таким образом, ваше выражение равно:

01100001 ИЛИ
01100101 ИЛИ
01100011 ИЛИ
01100001, и результат для этого - 01100111.

Или результаты 1, если в столбце есть хотя бы один раз 1.

01100001 преобразование в десятичный означает 103.
Мы снова перейдем к unicode-table, и мы увидим, что 103 в deciaml равно 'g'.

Итак, вы спросили, что делает эта функция, он вычисляет двоичное значение, затем преобразует его в десятичное значение и возвращает символ unicode.