21

これらの拡張メソッドと列挙型があります。

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はコンパイルされます。2番目はしません:

 if ((x.Y?.Color).IsOneOf(Color.Red, Color.Green))
 ;
 if (x.Y?.Color.IsOneOf(Color.Red, Color.Green))
 ;

それらは、余分な括弧のセットによってのみ異なります。なぜ私はこれをしなければならないのですか?

bool?最初は、 to からへの二重の暗黙的なキャストを行っているのではないかと疑っていましたが、最初の拡張メソッドを削除すると、 booltoからbool?の暗黙的なキャストがないと不平を言います。その後、IL を確認しましたが、キャストはありませんでした。逆コンパイルして C# に戻すと、次のようになります。boolbool?

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 行目で同じ問題が発生しない理由です。

ここに画像の説明を入力

4

4 に答える 4

0

System.Nullable<UserQuery+Color>次の行を配置すると、.net がこの null 条件式の動的型を括弧内に作成していることがわかります。

Console.WriteLine((x.Y?.Color).GetType().ToString());

括弧を入れないと、おそらく正規表現として評価しようとするため、エラーになります。

于 2016-05-24T20:08:07.690 に答える