驚くべきことに、次のコードはアサートに失敗します。
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
では、好奇心から、特定のインスタンスがNullable <>オブジェクトであるかどうかをどのように判断できますか?
まず、_Nullable<T>
_は構造体であるため、object自体はありません。 GetType()
を呼び出すことはできません。これは、値をボックス化するためです(この時点で、nullを取得して例外を取得するか、ボックス化されたnull不可能な値を取得して必要なタイプを取得しません)。
(ボクシングはここであなたの主張を台無しにしているものです-私はIsType
がobject
を受け入れると思います。)
ただし、型推論を使用して、変数の型を型パラメーターとして取得できます。
_public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
_
例のようにコンパイル時に正確な型がわかっている場合、これはそれほど多くは使用されませんが、ジェネリックスには役立ちます。 (もちろん、それを実装する別の方法があります。)
あなたの実際の状況はどうですか?コンパイル時にこれに対する答えを知っていることを考えると、これはこのようなアサーションではないと思います。
@ jon-skeetの回答が好きですが、テスト対象のタイプがわかっている場合にのみ機能します。私たちの世界では、リフレクションを使用してオブジェクトを開き、正規表現に対して値をテストしています。
あらゆるタイプで機能するように拡張機能を単純化することは、私たちにとってより効果的でした。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
ジェネリックは生命の血ですが、時々... :)
int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
これが私が思いついたものです。他のすべてが失敗したように見えたので、少なくともポータブルクラスライブラリ/DotNet Core with> = C#6
基本的に、ジェネリック型Object
と_Nullable<T>
_を拡張し、基になる型に一致する静的拡張メソッドが呼び出され、ジェネリックT
拡張よりも優先されるという事実を使用します-方法。
_public static partial class ObjectExtension
{
public static bool IsNullable<T>(this T self)
{
return false;
}
}
_
1つは_Nullable<T>
_用です
_public static partial class NullableExtension
{
public static bool IsNullable<T>(this Nullable<T> self) where T : struct
{
return true;
}
}
_
Reflectionと_type.IsGeneric
_およびtype.GetGenericParameters()
の使用は、現在の.NETランタイムのセットでは機能しませんでした。
Assert
はどの名前空間にありますか?
以下は、予想どおりtrue
を返します。
_int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
_
typeof(Nullable<int>).IsInstanceOfType(42)
もtrueを返すことに注意してください。これは、このメソッドがobject
を受け入れるため、_Nullable<int>
_としてボックス化されるためです。