型が構造体かクラスかをプログラムで確認する方法は?
使用する - Type.IsValueType
:
Typeが値型かどうかを示す値を取得します。
次のように使用します。
typeof(Foo).IsValueType
または次のような実行時:
fooInstance.GetType().IsValueType
逆に Type.IsClass
プロパティ(私の意見ではIsReferenceType
と呼ばれるべきでしたが、問題ではありません)。これは、テスト対象に基づいて、用途に適している場合とそうでない場合があります。
コードは常にブール否定なしで読みやすくなるので、コードの読みやすさに役立つ方を使用します。
Stefanが以下で指摘するように、構造体を正しく識別するためには、enums
に関して誤検知を回避するように注意する必要があります。 enum
は値のタイプであるため、IsValueType
プロパティはtrue
およびenums
に対してstructs
を返します。
したがって、一般的に値型だけでなくstructs
を本当に探している場合は、次のようにする必要があります。
Type fooType = fooInstance.GetType();
Boolean isStruct = fooType.IsValueType && !fooType.IsEnum;
Type type = typeof(Foo);
bool isStruct = type.IsValueType && !type.IsPrimitive;
bool isClass = type.IsClass;
それでも、プリミティブ型またはインターフェースである可能性があります。
編集:構造体の定義については多くの議論があります。構造体と値の型は実際には同じなので、IsValueType
が正解です。私は通常、型がユーザー定義のstructであるかどうかを知る必要がありました。これは、プリミティブ型ではなく、キーワードstruct
を使用して実装される型を意味します。だから私と同じ問題を抱えているすべての人のために私の答えを保ちます。
編集2: C#リファレンス によると、列挙型は構造体ではありませんが、他の値型は構造体です。したがって、型が構造体であるかどうかを判断する正しい答えは次のとおりです。
bool isStruct = type.IsValueType && !type.IsEnum;
私見、構造体の定義は論理的であるよりも混乱します。私は実際に、この定義が実践において何らかの関連があるとは疑っています。
拡張メソッド。これは、コードでtrue
として定義されているものに対してはstruct
を返しますが、技術的に構造体ではありますが、int
のようなものに対しては返しません。
型に子フィールドまたはプロパティが含まれている可能性があるが、struct
ではなくclass
として定義されていることを知る必要がありました。 struct
を変更すると、コピーが変更されるだけなので、変更を「固定」するには、元のファイルを変更されたコピーに戻す必要があります。
public static bool IsStruct(this Type source)
{
return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}
以下をお試しください
bool IsStruct(Type t) {
return t.IsValueType;
}
すべての値タイプについて、System.ValueType
から派生する対応する自動生成クラスタイプがあり、これはSystem.Object
から派生します。値タイプ自体は何からも派生しないことに注意してください。 暗黙的に変換可能 そのクラス型に変換され、そのクラス型のインスタンスは明示的に値型に変換されます。
検討してください:
public static int GetSomething <T>(T enumerator)where T:IEnumerator <int> { T enumerator2 = enumerator; enumerator.MoveNext(); enumerator2.MoveNext(); return enumerator2.Current; }
List<int>.Enumerator
型の変数でこのルーチンを呼び出すと、IEnumerator<int>
型の変数で呼び出すと、List<int>.Enumerator
のインスタンスが格納されている場合とはまったく異なる動作になります。 List<int>.Enumerator
型の変数は値型ですが、List<int>.Enumerator
型の変数に格納されているIEnumerator<int>
のインスタンスは、クラス型として動作します。