Default value of any type.

G

GeezerButler

For any given type i want to know its default value.

There is a neat keyword called default for doing this like
object x = default(DateTime);
but I have an instance of Type (called someType) and something like
this cant work
object x = default(someType);

Is there any nice way of doing this? I dont really want to write a
huge switch block enumerating all types in .NET !
 
M

Marc Gravell

Generics might help, since default(T) will work fine...
If this isn't an option, you can make life a little simpler: only
value-types have a non-null result, and value-types have a default
ctor (kind-of) - so:

object obj = type.IsValueType ?
Activator.CreateInstance(type) :
obj = null;

Note that since it is boxed, for Nullable<T> you will get null, not an
boxed empty value - which is probably what you want anyway.

Marc
 
M

Marc Gravell

(copy paste glitch - should have read:)

object obj = type.IsValueType ?
Activator.CreateInstance(type) : null;
 
J

Jon Skeet [C# MVP]

For any given type i want to know its default value.

There is a neat keyword called default for doing this like
object x = default(DateTime);
but I have an instance of Type (called someType) and something like
this cant work
object x = default(someType);

Is there any nice way of doing this? I dont really want to write a
huge switch block enumerating all types in .NET !

For value types, you can always use Activator.CreateInstance(someType)
as there's guaranteed to be a parameterless constructor.
For reference types, the default value is always null.

You can tell the difference using Type.IsValueType.

Jon
 
A

Alun Harford

GeezerButler said:
For any given type i want to know its default value.

There is a neat keyword called default for doing this like
object x = default(DateTime);
but I have an instance of Type (called someType) and something like
this cant work
object x = default(someType);

Is there any nice way of doing this? I dont really want to write a
huge switch block enumerating all types in .NET !

Basically, there isn't a very nice way. I have an extension method that
does something like (don't have the code on me):

public class Extension
{
public static object GetDefault(this Type type)
{
return
typeof(Extension).GetMethod("GetDefaultImp").MakeGenericMethod(type).Invoke(null,
new Type[0]);
}
public static T GetDefaultImp<T>()
{
return default(T);
}
}

(If you're not using C# 3, you can do that as plain old static utility
methods)

Note that this is fairly slow. If you need to do this lots, you're
better doing it 'properly' (checking to see if you've got a value or
reference type and returning Activator.CreateInstance(type) or null.

Alun Harford
 
J

Jon Skeet [C# MVP]

Note that this is fairly slow. If you need to do this lots, you're
better doing it 'properly' (checking to see if you've got a value or
reference type and returning Activator.CreateInstance(type) or null.

Given that the "proper" way is only about 4 lines of code, what's the
advantage of using the MakeGenericMethod way?
 
B

Ben Voigt [C++ MVP]

Note that this is fairly slow. If you need to do this lots, you're better
doing it 'properly' (checking to see if you've got a value or reference
type and returning Activator.CreateInstance(type) or null.

If you're going to do this lots, construct an appropriate delegate "delegate
object ObjectReturnerDelegate()" from the MethodInfo or ConstructorInfo and
cache this in a Dictionary<Type,ObjectReturnerDelegate>

A delegate call is much faster than reflection.
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
If you're going to do this lots, construct an appropriate delegate "delegate
object ObjectReturnerDelegate()" from the MethodInfo or ConstructorInfo and
cache this in a Dictionary<Type,ObjectReturnerDelegate>

A delegate call is much faster than reflection.

Except that you've got to use reflection to *get* the method call in
the first place. Rather than caching a delegate, it makes more sense
(IMO) to cache the actual value - and only for value types, at that:

// Thread-safety not shown here
static readonly Dictionary<Type,object> cache =
new Dictionary<Type,object>();

static object GetDefaultValue(Type t)
{
if (!t.IsValueType)
{
return null;
}
object ret;
if (cache.TryGetValue(t, out ret))
{
return ret;
}
ret = Activator.CreateInstance(t);
cache[t] = ret;
return t;
}
 
A

Alun Harford

Jon said:
Given that the "proper" way is only about 4 lines of code, what's the
advantage of using the MakeGenericMethod way?

It's clearer, in my opinion.

Alun Harford
 
A

Alun Harford

Ben said:
If you're going to do this lots, construct an appropriate delegate "delegate
object ObjectReturnerDelegate()" from the MethodInfo or ConstructorInfo and
cache this in a Dictionary<Type,ObjectReturnerDelegate>

A delegate call is much faster than reflection.

If you're doing this lots, your design and/or choice of language is
probably very poor.

Alun Harford
 
J

Jon Skeet [C# MVP]

Alun Harford said:
It's clearer, in my opinion.

Anyone reading that code has to understand generic methods and
accessing generic methods via reflection. With the simple
Activator.CreateInstance all you need to know is what CreateInstance
does (and that's reasonably common) and that all value types have a
parameterless constructor.

I certainly think CreateInstance is clearer and simpler. It's all a
matter of opinion though, yes.
 
A

Alun Harford

Jon said:
Anyone reading that code has to understand generic methods and
accessing generic methods via reflection.

Except for by reflection, I can't think of many times you get an object
and don't know if it's a value type or a reference type.

The only other situation I can think of is interfacing with legacy
pre-generics code. Eugh! :)

Alun Harford
 
J

Jon Skeet [C# MVP]

Alun Harford said:
Except for by reflection, I can't think of many times you get an object
and don't know if it's a value type or a reference type.

Absolutely - but when generics and reflection mix, life gets pretty
nasty in my experience. I'd rather avoid that wherever possible.

Another benefit is that the Activator.CreateInstance version works in
..NET 1.1 as well :)
 
B

Ben Voigt [C++ MVP]

Jon Skeet said:
Except that you've got to use reflection to *get* the method call in
the first place. Rather than caching a delegate, it makes more sense
(IMO) to cache the actual value - and only for value types, at that:

Yes, I'm stupid :) Thanks for pointing out the obvious.

For cases other than the default constructor of a value type.... do what I
said.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top