Programmatic equivalent of default(Type)

Viewed 165919

I'm using reflection to loop through a Type's properties and set certain types to their default. Now, I could do a switch on the type and set the default(Type) explicitly, but I'd rather do it in one line. Is there a programmatic equivalent of default?

13 Answers
  • In case of a value type use Activator.CreateInstance and it should work fine.
  • When using reference type just return null
public static object GetDefault(Type type)
{
   if(type.IsValueType)
   {
      return Activator.CreateInstance(type);
   }
   return null;
}

In the newer version of .net such as .net standard, type.IsValueType needs to be written as type.GetTypeInfo().IsValueType

I do the same task like this.

//in MessageHeader 
   private void SetValuesDefault()
   {
        MessageHeader header = this;             
        Framework.ObjectPropertyHelper.SetPropertiesToDefault<MessageHeader>(this);
   }

//in ObjectPropertyHelper
   public static void SetPropertiesToDefault<T>(T obj) 
   {
            Type objectType = typeof(T);

            System.Reflection.PropertyInfo [] props = objectType.GetProperties();

            foreach (System.Reflection.PropertyInfo property in props)
            {
                if (property.CanWrite)
                {
                    string propertyName = property.Name;
                    Type propertyType = property.PropertyType;

                    object value = TypeHelper.DefaultForType(propertyType);
                    property.SetValue(obj, value, null);
                }
            }
    }

//in TypeHelper
    public static object DefaultForType(Type targetType)
    {
        return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
    }

Slight adjustments to @Rob Fonseca-Ensor's solution: The following extension method also works on .Net Standard since I use GetRuntimeMethod instead of GetMethod.

public static class TypeExtensions
{
    public static object GetDefault(this Type t)
    {
        var defaultValue = typeof(TypeExtensions)
            .GetRuntimeMethod(nameof(GetDefaultGeneric), new Type[] { })
            .MakeGenericMethod(t).Invoke(null, null);
        return defaultValue;
    }

    public static T GetDefaultGeneric<T>()
    {
        return default(T);
    }
}

...and the according unit test for those who care about quality:

[Fact]
public void GetDefaultTest()
{
    // Arrange
    var type = typeof(DateTime);

    // Act
    var defaultValue = type.GetDefault();

    // Assert
    defaultValue.Should().Be(default(DateTime));
}

This should work: Nullable<T> a = new Nullable<T>().GetValueOrDefault();

Related