У меня есть эти методы расширения и тип перечисления:
public static bool IsOneOf<T>(this T thing, params T[] things)
{
return things.Contains(thing);
}
public static bool IsOneOf<T>(this T? thing, params T[] things) where T : struct
{
return thing.HasValue && things.Contains(thing.Value);
}
public enum Color { Red, Green, Blue }
Первый if
ниже компилируется; вторая не делает:
if ((x.Y?.Color).IsOneOf(Color.Red, Color.Green))
;
if (x.Y?.Color.IsOneOf(Color.Red, Color.Green))
;
Они зависят только от дополнительного набора круглых скобок. Почему я должен это делать?
Сначала я подозревал, что он выполнял двойное неявное преобразование с bool?
до bool
, а затем обратно на bool?
, но когда я удаляю первый метод расширения, он жалуется, что нет никакого неявного перевода из bool
до bool?
. Затем я проверил ИЛ и не было отливок. Декомпиляция обратно на С# приводит к тому, что выглядит следующим образом:
if (!(y != null ? new Color?(y.Color) : new Color?()).IsOneOf<Color>(new Color[2]
{
Color.Red,
Color.Green
}));
который подходит для версии CLR, в которой я запущен, и чего я ожидаю. Я не ожидал, что x.Y?.Color.IsOneOf(Color.Red, Color.Green)
не компилируется.
Что происходит? Это просто способ реализации языка, для которого требуется ()
?
Обновление
Вот экранная надпись, показывающая ошибку в контексте. Это становится еще более запутанным для меня. Ошибка действительно имеет смысл; но то, что нет (на мой взгляд, сейчас), почему строка 18 не будет иметь одинаковую проблему.