Update: Кажется, что я не совсем понимаю, что именно я спрашиваю (и, поскольку вопрос был разработан с течением времени, я также немного потерял трек), поэтому вот версия tl; dr:
var test1 = a is byte & b; // compiles
var test2 = a is byte? & b; // does not compile
var test3 = a is byte? && b; // compiles
Это означает, что, как я понимаю, модификатор типа ?
имеет более низкий приоритет (поскольку это не оператор, это может быть не лучшее слово), чем оператор &
, но выше, чем оператор &&
. Это так? Где это описано в стандарте?
И исходный вопрос:
Пытаясь выяснить ответ на вторую головоломку от отличного blogpost от Jon Skeet, "Сказка о двух головоломках" , я столкнулся с проблемой
unsafe private void Test<T>(T a, bool b)
{
var test1 = a is byte? & b; // does not compile
var test2 = a is byte? && b; // compiles
var test3 = a is byte ? & b : & b; // compiles
}
Здесь я использую контекст unsafe
, так как моя фактическая цель требует его (например, третья строка), но нет необходимости воспроизводить проблему, которую я поднимаю. (Однако это может иметь эффект, поскольку он вводит адрес-оператора в качестве альтернативы для символа &
.)
Первая строка не компилируется (другие делают), она дает следующее сообщение об ошибке:
Syntax error, ':' expected
Это означает, что в этом случае компилятор видит строку как
var test1 = (a is byte) ? &b [: missing part that it complains about];
Пока во второй строке это выглядит как:
var test2 = (a is byte?) && (b);
Я проверил приоритет оператора (здесь), а порядок (от самого высокого до самого низкого) выглядит следующим образом: &, &&, ?:
, поэтому это один не объясняет, почему первая строка не компилируется, пока вторая делает (или, по крайней мере, не для меня - может быть, это то, где я ошибаюсь...) Изменить: Я понимаю, почему второй компилирует, поэтому, пожалуйста, не концентрируйтесь на этом в своих ответах.
Моя следующая догадка заключалась в том, что каким-то образом приоритет (если есть такая вещь) для модификатора типа ?
находится где-то между этими двумя (или фактически тремя) операторами (&
и &&
). Неужели так? Если бы кто-то не смог объяснить точное поведение, которое я испытываю? Является ли порядок оценки модификатора типа ?
четко описанным где-то в стандарте?
Изменить: Я также знаю, что есть унарный адрес оператора (на самом деле это трюк, который я пытаюсь использовать для решения...), который играет здесь роль, но мой вопрос по-прежнему остается прежним.
В том же unsafe
контексте они с радостью компилируются:
var test1 = true & b;
var test2 = true && b;
// or
var test1 = a is byte & b;
var test2 = a is byte && b;
Поэтому я думаю, что он должен быть связан с ?
модификатором/оператором, а не только с приоритетом адреса оператора (иначе две строки test1
не будут компилироваться).
P.S.: Я знаю, что я могу добавить круглые скобки в свой код, поэтому он будет компилироваться, но я хочу этого избежать:
var test = (a is byte?) & b; // compiles
Update: Я немного экспериментировал с Рослином, и я подумал, что было бы неплохо приложить АСТ к различным утверждениям:
var test1 = a is byte & b;
var test2 = a is byte? & b;
var test3 = a is byte? && b;
Я хочу подчеркнуть, что я не ищет решение исходной проблемы в связанной статье (конечно, я ищу ее, но я прошу вас не давать ответ здесь, пожалуйста, поскольку я хотел бы это узнать самостоятельно.) Кроме того, пожалуйста, не комментируйте, если я нахожусь на совершенно неправильном пути в поиске решения, я только упомянул загадку, чтобы дать некоторый контекст для моей конкретной проблемы, и предоставить достаточно хорошее оправдание для написания кода, подобного этому.