1

I saw a question and answer in stack overflow

How to check if an object is nullable?

I could not put a comment in the above because I do not have more than 50 comments and that is why I am asking a question in here.

if(Nullable.GetUnderlyingType(myType) !=null)
{
   // It's Nullable
}

If myType is system.string

Nullable.GetUnderlyingType(myType) 

returns null

I thought System.string is null-able !

Community
  • 1
  • 1
Yazid Arezki
  • 33
  • 1
  • 4

5 Answers5

4

The call Nullable.GetUnderlyingType() doesn't return anything meaningful for typeof(string). The documentation mentions:

Returns the underlying type argument of the specified nullable type.

Return Value

The type argument of the nullableType parameter, if the nullableType parameter is a closed generic nullable type; otherwise, null.

In other words, it only returns something useful if you actually pass it a type that implements Nullable<T>, for example int?, bool?, and so on. That is what's being meant by a "nullable type" here.

You can also see its intended usage in the code from Marc's answer to the question you link to:

static bool IsNullable<T>(T obj)
{
    // ...
    if (!type.IsValueType) return true; // ref-type
    if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
}
Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
3

Nullable<T> - is a special structure, so System.string is not Nullable<T>, System.string is a class. All classes can be null. So,

if (myType.IsClass)
{
    //can be null
}
Backs
  • 24,430
  • 5
  • 58
  • 85
1

All reference types can be set to null, but are not of the Nullable<T> type, you can check if a type is a reference type by using !myType.IsValueType

Stuart
  • 5,358
  • 19
  • 28
1

System.String (or string) is a reference type. This means, instances of this type can be null. Nullables are a way to add this functionality to value types (like the primitive types bool, int etc.).

Lukas Körfer
  • 13,515
  • 7
  • 46
  • 62
1

Nullable is a type, not a property of a type. System.String is nullable, but it is not a Nullable, unlike int?, which is a shortcut for Nullable<System.Int32>. All reference types in C# are nullable (you can pass a null reference), while the Nullable type can only accept a non-nullable value type as an argument.

If you want to check if a given type can accept null as a value, you can do something like this:

bool CanBeNull<T>()
{
  return default(T) == null;
}

Of course, this already makes the assumption that the default value is the null value, which isn't necessarily the case; but it will work for both reference types and Nullable value types. If you have to deal with a value type that accepts null but not as the default value, you'll have to add it specifically. There isn't really a sure and simple way to check if a given type can be assigned null other than actually trying to assign a null value.

Indeed, what "can be assigned null" means is something that depends very much on the compiler. For example, doing something like int? someValue = null; actually calls the constructor of int? - it's equivalent to int? someValue = new int?();.

If you don't know the type at compile-time (so you can't use generics), you can add a check for whether the given type is a value type:

if (!type.IsValueType) // Can be assigned null

Make sure you treat classes, value types and interfaces correctly. And of course, just being able to assign a null value to a local/field doesn't mean it's necessarily a valid value. In the end, the decision is yours.

Luaan
  • 62,244
  • 7
  • 97
  • 116