How to hinder reflection-based scenarios

In one easy step:  Make sure an object’s runtime type doesn’t actually match its compile-time type.  This test fails:

public void HoorayNullables()
    int? i = 5;

With a rather unexpected error message of:

Expected: <System.Nullable`1[System.Int32]>
But was:  <System.Int32>

Hmmm, that’s interesting, I wouldn’t expect an object to straight up lie to me about its type.  Even more irritating when you design a framework to examine runtime types of objects to make determinations on what to do.  This is by design, so that nullable types play as nice as possible with their underlying type counterparts.  That’s why you also see the implicit/explicit conversion operators as well.  There isn’t a way, as far as I can tell, to take an instance of an object by itself and determine if it’s a nullable type or not.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in C#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • David Williams

    There is a way:

    Type type = i.GetType();
    if (type.IsGenericType && type.GetGenericTypeDefination.Equals(typeof(Nullable<>))
    // Handle Nullable types

  • Nullable is a bit weird in that it is implemented as Nullable<> but the behaviour is the one of a reference type.
    The value of a int? is null or int. That’s why i.GetType() returns Int32.
    As explained in the StackOverflow answer, the nullability can is preserved by reflection (on methods arguments/return values) and generic parameters. You can then use Nullable.GetUnderlyingType() that returns null if the type is not nullable.

  • @David

    No, that doesn’t work. i.GetType() returns typeof(int), not int?.

  • ulu

    You could use a small VB.Net utility. Looks nasty, but you’ve got the idea ;) (It uses VB’s late binding, so if you don’t have a property called “HasValue”, it throws an exception). I haven’t tried it myself, it *might* use GetType behind the scenes, in which case it doesn’t work as well.

    Public Function IsNullable(value as Object) As Boolean
    Dim x = value.HasValue
    Return True
    Return False
    End Try
    End Function