web-dev-qa-db-ja.com

C#リフレクション:Nullable <int>の型を取得する方法?

私がやりたいことは次のようなものです:

switch( myObject.GetType().GetProperty( "id") )
{
    case ??: 
        // when Nullable<Int32>, do this
    case ??:
        // when string, do this
    case ??:
        // when Nullable<bool>, do this

Object.GetType()の下のどのパスに、caseステートメントを使用して比較できるデータ型の文字列名がありますか?リフレクションを使用してmyObjectの値を設定する多くのConvert.ToInt32(string)の1つを使用できるように、タイプを知る必要があります。

31
Zachary Scott

更新:この質問の質問者がしようとしていたように、C#7はTypesの切り替えをサポートするようです。少し異なりますが、構文の地雷に注意してください。

比較するために文字列名は必要ありません:

if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<Int32>))
    // when Nullable<Int32>, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(string))
    // when string, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<bool>))
    // when Nullable<bool>, do this
13
M.Babcock

次のタイプのコードを使用して、タイプがnull可能かどうかを確認し、実際のタイプを取得しています。

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    return Nullable.GetUnderlyingType(type);
}

タイプが例えばNullableこのコードはint部分(基になる型)を返します。オブジェクトを特定のタイプに変換する必要があるだけなら System.Convert.ChangeType メソッド。

63
Toni Parviainen

質問は非常に混乱しています。 「myObject」はnull許容のintである可能性のあるオブジェクトですか?または、プロパティ「id」はおそらくnull許容型の整数ですか?

前者の場合、それは虚偽を前提としているため、あなたの質問には答えられません。ボックス化されたnull許容intのようなものはありません。したがって、if (myobject.GetType() == typeof(int?))を提案するすべての回答は正しくありません。条件が真になることはありません。

Null可能なintをオブジェクトに変換すると、それはnull参照になる(null可能なintに値がない場合)か、ボックス化されたintになる。オブジェクトneverにnull許容のintが含まれているため、オブジェクトにnull許容のintが含まれているかどうかを判断する方法はありません。

後者の場合は、プロパティタイプtypeof(int?)と比較します。スイッチは使用できません。スイッチケースに使用できるのは定数のみで、型は定数ではありません。

とはいえ、これはコードの悪臭です。そもそもなぜリフレクションを使用しているのですか?

18
Eric Lippert

.netでは、値型のインスタンスはビットのコレクションであり、関連する型情報はありません。ただし、Nullable<T>以外のすべての値タイプについて、システムはSystem.ValueTypeから派生する対応するクラスタイプも自動生成します。値型から自動生成クラス型への拡大変換と、自動生成クラス型から値型への縮小変換が存在します。 Nullable<T>の場合、値の型との間の変換を伴う、自動生成されたクラスの型はありません。代わりに、拡大変換はNullable<T>Tに関連付けられたクラス型の間の両方向に存在します。

私の知る限り、この奇妙な動作はnullと空のNullable<T>を比較してtrueを返すことができるように実装されました。

2
supercat

@Cody Greyが言ったように、もしステートメントがおそらく最善の方法であるかどうか

var t = myObject.GetType();

if (t == typeof(Nullable<int>))
{ }
else if (t == typeof(string))
{}
else if (t==typeof(Nullable<bool>))
{}
0
heads5150