web-dev-qa-db-ja.com

C#7.3列挙型制約:列挙型キーワードを使用できないのはなぜですか?

ジェネリック型パラメーターを列挙型に制約するために、以前に次のように制約しました。これは、C#7.3より前の列挙型の型Tを制約するのに最適な方法でした。

void DoSomething<T>() where T : struct, IComparable, IConvertible, IFormattable

現在、C#7.3では、ジェネリック型をSystem.Enumに制約する新しい機能が追加されています。 VS2017 15.7アップデートが今日リリースされました でenum制約を使用してみましたが、次のように記述すると正常にコンパイルされます(using System;ディレクティブがある場合):

void DoSomething<T>() where T : Enum

ただし、enumキーワードを使用しても機能せず、コンパイラーは次のエラーをスローします(メソッド本体が必要ですが、ここで言及する価値はありません)。

void DoSomething<T>() where T : enum
                                ^ error CS1031: Type expected
                                  error CS1002: ; expected
                                    ^ error CS1001: Identifier expected
                                      error CS1514: { expected
                                      error CS1513: } expected

構造に対してstruct制約が機能するため、enumが列挙型に対して機能しない理由がわかりません。 enumは、intInt32に対して行うような実際の型にマッピングされないのは事実ですが、struct制約と同じように動作するはずだと思いました。

まだ完全に実装されていない実験的な機能トラップに陥ったのですか、それとも仕様で意図的に行われたのですか?

19
Ray

ジェネリックのstruct制約は、実際の型にはマッピングされません(理論的には ValueType にマッピングできます)。同様に、enumstringint、またはlongのように実際の型にきれいにマッピングせず、クラスを作成するための特別な構文を設定します整数値にマップする記号定数の;したがって、public enum Stuffではなくpublic class Stuff : Enumになります。後者が代わりに実装されていた場合、非classキーワードに基づいて構文を変更するのではなく、継承されたタイプに基づいて構文を変更するため、より微妙になることに注意してください。

そのため、結論として、はい、enumはキーワードであり、タイプエイリアスではないため、where T : enumは機能しません。あなたが本当にそれが動作するのを見たいなら、enumは少なくともこれらのようなコンテキストのタイプエイリアスのようなにおいがするので、それをリクエストしてください!

編集:いくつかの歴史的な参照については、 2008年からの質問です は特別なクラスであるため、Enumが有効な制約ではなかったことを示しています。

12
David