我有这些扩展方法和枚举类型:
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?
tobool
然后返回到的双重隐式转换bool?
,但是当我删除第一个扩展方法时,它抱怨没有隐式转换 from bool
to bool?
。然后我检查了IL,没有演员表。反编译回 C# 会产生如下所示的内容:
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 行不会有同样的问题。