Whats the use of Nullable.GetUnderlyingType, if typeof(int?) is an Int32?

前端 未结 5 2107
萌比男神i
萌比男神i 2021-02-05 16:07

why is typeof int? an Int32

int? x = 1;
Console.WriteLine(x.GetType().Name);

If it is okay then what\'s the use of

相关标签:
5条回答
  • 2021-02-05 16:20

    Mainly its for dealing with a generic method:: e.g.

    public static void SomeMethod<T>(T argument)
    {
         if(Nullable.GetUnderlyingType(typeof(T) != null)
         {
                 /* special case for nullable code go here */
         }
         else
         {
                /* Do something else T isn't nullable */
         }
    }
    

    It's important to know this, as certain things that are very cheap can be wildly expensive on nullable's. For instance, if(argument == null) is normally super cheap, but when done in a generic method on a Nullable<T> is forced to box the argument to get a null reference. Your best bet is to use EqualityComparer<T>.Default which will slow everything else down, but makes nullable's not suffer.

    0 讨论(0)
  • 2021-02-05 16:28

    Calling GetType() boxes your variable. The CLR has a special rule that Nullable<T> gets boxed to T. So x.GetType will return Int32 instead of Nullable<Int32>.

    int? x = 1;
    x.GetType() //Int32
    typeof(int?) //Nullable<Int32>
    

    Since a Nullable containing null will be boxed to null the following will throw an exception:

    int? x = null;
    x.GetType() //throws NullReferenceException
    

    To quote MSDN on Boxing Nullable Types:

    Objects based on nullable types are only boxed if the object is non-null. If HasValue is false, the object reference is assigned to null instead of boxing

    If the object is non-null -- if HasValue is true -- then boxing occurs, but only the underlying type that the nullable object is based on is boxed. Boxing a non-null nullable value type boxes the value type itself, not the System.Nullable<T> that wraps the value type.

    0 讨论(0)
  • 2021-02-05 16:28

    When you write int? it's as if you've written Nullable<int>. That's the type you're looking for, I think.

    0 讨论(0)
  • 2021-02-05 16:33

    Its for when you don't know its Int32.

    Example:

        public Type GetNullableUnderlyingType<T>(Nullable<T> obj) 
            where T : struct
        {
            return Nullable.GetUnderlyingType(typeof(Nullable<T>));
        }
    

    Here, you can pass any Nullable object and get it to return it's underlying type.

    0 讨论(0)
  • 2021-02-05 16:45

    This example is a bit confused, because:

    int? x = 1;
    

    creates a Nullable<int> like you expect; however:

    Type tupe = x.GetType();
    

    is a call to a non-virtual method on object, which isn't (and can't be) overridden - therefore this is a boxing operation; and Nullable<T> has special boxing rules:

    • if it is empty, it boxes to null
    • if it has a value, the value is boxed and returned

    i.e.

    int? x = 1;
    int y = 1;
    

    box to exactly the same thing.

    Therefore, you are passing typeof(int) to GetUnderlyingType.

    A more illustrative example of when this helps is when using reflection:

    class Foo {
        public int? Bar {get;set;}
    }
    ...
    Type type = typeof(Foo); // usually indirectly
    foreach(var prop in type.GetProperties()) {
         Type propType = prop.PropertyType,
              nullType = Nullable.GetUnderlyingType(propType);
    
         if(nullType != null) {
             // special code for handling Nullable<T> properties;
             // note nullType now holds the T
         } else {
             // code for handling other properties
         }
    }
    
    0 讨论(0)
提交回复
热议问题