views:

99

answers:

3

In c# I can use default(T) to get the default value of a type. I need to get the default type at run time from a System.Type. How can I do this?

E.g. Something along the lines of this (which doesn't work)

var type = typeof(int);
var defaultValue = default(type);
+4  A: 

If you're trying to build an expression tree, use Expression.Default:

Expression expression = Expression.Default(type);

One other way you could do this fairly easily would be:

object defaultValue = Array.CreateInstance(type, 1).GetValue(0);

Ugly, but it'll work :) Note that it's hard to get the default value of a nullable type, as it will always be boxed to a null reference.

Jon Skeet
I'm generating expression trees for use with Mindscape Lightspeed, but their query provider doesn't support `DefaultExpression`, so I need the actual value to put inside a `ConstantExpression`.
GiddyUpHorsey
+3  A: 

That's pretty easy, you just have 2 cases to consider:

  • reference types: the default value is always null
  • value types: you can easily create an instance using Activator.CreateInstance

    public static object GetDefaultValue(Type type)
    {
        if (type.IsValueType)
        {
            return Activator.CreateInstance(type);
        }
        else
        {
            return null;
        }
    }
    

You could also consider using FormatterServices.GetUninitializedObject instead of Activator.CreateInstance, it's probably faster.

Thomas Levesque
Have you tried running your code? It won't work, and the reason is that value types do not (normally) have a default constructor. They do in C#, but it's a fiction; on CLR level there is none, and `initobj` is used in IL.
Pavel Minaev
@Pavel, you're right, I never realized that there wasn't a real default constructor... I changed it to Activator.CreateInstance, and it works fine
Thomas Levesque
+3  A: 

For a reference type return null, for a value type, you could try using Activator.CreateInstance or calling the default constructor of the type.

public static object Default(Type type)
{
   if(type.IsValueType)
   {
      return Activator.CreateInstance(type);
   }

   return null;
}
madgnome
Shortly after writing my question I came up with `return Expression.Lambda<Func<object>>(Expression.Convert(Expression.Default(type), typeof (object))).Compile()();`, but yours is so much nicer.
GiddyUpHorsey
@Giddy: that would be a very expensive way to do it, since you're compiling the expression tree to IL (and then JIT will have to compile it to native) on every invocation.
Pavel Minaev
Yes, I agree. Which is why I'm not using it, and am using madgnome's solution instead. Although, it was the shorter and more readable code, not performance, that pushed me to use his one. Performance isn't too big of a deal for my scenario.
GiddyUpHorsey