Miscellaneous Debris

Avner Kashtan's Frustrations and Exultations
Non-generic default values in C#? Why not?!

A relatively obscure new keyword in C# 2.0 is the default(T) keyword.
It's shorthand for checking if the given generic parameter T is a value type or reference type. If it's a reference type, it returns null. Otherwise it returns 0/false/0.0 or whatever the default value for the type is.

For some reason, though, it can only be used on generic parameters. Why can't I use default(typeof(int)) to get 0? Or, more realistically, default(myUnknownType) to return the default value?

A workaround is to check if it's a value type with reflection, but it's cumbersome:

if (!myType.IsValueType)
{
   return null;
}
else
{
   return Activator.CreateInstance(myType);
}

Luckily, value types (including structs) always have a default parameterless constructor. We can't even override it - it will always initialize all struct members to their default values.

This little code snippet can now be wrapper in some sort of function - call it Default() or GetDefault() or even @default() if you want to keep it as close as possible to the generic keyword.

It's interesting to note that the generic keyword relies on the InitObj IL opcode to initialize the object. If we could embed IL directly in our code we could call this directly. We can do it via Reflection.Emit and DynamicMethods but I feel that's going a bit far overboard when the solution above works just as well.

Published Sunday, May 21, 2006 11:58 AM by AvnerK

Filed under: , , ,

Comments

# re: Non-generic default values in C#? Why not?!@ Sunday, May 21, 2006 8:33 AM

Instead of

int i = default(typeof(int));

Why don't you use?

int i = new int();

Gabriel Lozano-Morán

# re: Non-generic default values in C#? Why not?!@ Sunday, May 21, 2006 9:05 AM

Use default(int) instead of default(typeof(int))

default(T) takes a type name, not a type value.

However, this feature is not useful outside generics... because for value types you can use new T() and for reference types, null...

Wesner Moise

# re: Non-generic default values in C#? Why not?!@ Sunday, May 21, 2006 9:45 AM

Yes, as you can see from the rest of my post this is exactly what I do - I instantiate the value type with the default constructor.

I'm just saying it would be nicer to have the shorter syntax - default(myType), for instance.

Avner Kashtan

# re: Non-generic default values in C#? Why not?!@ Sunday, May 21, 2006 4:22 PM

If anyone cares about this, you can vote on the language suggestion I opened on Ladybug to extend the default() keyword to all types:
http://lab.msdn.microsoft.com/ProductFeedback/viewFeedback.aspx?feedbackId=FDBK50235

Avner Kashtan

# re: Non-generic default values in C#? Why not?!@ Monday, May 22, 2006 7:40 PM

You missed my point....

The feature you requested already exists...

You typed it wrong.. default(myType) works everywhere. but default(typeof(myType)) works nowhere.

Wesner Moise

# re: Non-generic default values in C#? Why not?!@ Tuesday, May 23, 2006 3:00 AM

Werner - that's exactly my point. I can do default(int) right now, or default(float) or even default(myStruct), but I can't do a default(myRuntimeType). If I received a Type object and want to return that type's default value I have to use the function I outlined above, rather than using a clearer, more concise language construct such as default(type).

AvnerK

# re: Non-generic default values in C#? Why not?!@ Wednesday, May 24, 2006 6:13 PM

Dude, I believe that you are totally abusing the default keyword. You should only use it in Generics to assign a default value to your parameterized type. Using it outside generics you should call the constructor of the type as I posted earlier

int i = new int();
float f = new float();
MyObject mo = new MyObject();

Gabriel Lozano-Morán

# re: Non-generic default values in C#? Why not?!@ Wednesday, May 24, 2006 8:27 PM

I think I finally understand what you mean and the answer is no you can't and here is why: you are trying to dynamically create types (thus during runtime) based on another runtime type. You are mixing compile-time with run-time here.

Gabriel

# re: Non-generic default values in C#? Why not?!@ Wednesday, May 24, 2006 11:46 PM

Mixing compile-time and run-time is what Reflection is all about. As my sample above shows, I can achieve my goal using Activator.CreateInstance today - I instantiate a new value type at runtime using a type that's unspecified at compile time. What I want is a better way to do what that snippet does - initialize a variable without having to go through its constructor and the Activator methods and everything.

Avner Kashtan

# re: Non-generic default values in C#? Why not?!@ Thursday, May 25, 2006 8:25 AM

It has to do with the type-safety checks in the CLR why this is not allowed. When you use Generics this will be JIT-ted which you still cannot compare with Reflection.

Gabriel

# re: Non-generic default values in C#? Why not?!@ Tuesday, September 12, 2006 2:46 PM

Thanks! Needed that little snippet; here's my usage to get some data over ADO.NET:

// Generic version

public static T ReadValue<T>(object value)

{

 return value == DBNull.Value ? default(T) : (T) value;

}

// Runtime Type version

public static object ReadValue(object value, Type targetType)

{

 object defaultValue = targetType.IsValueType ? Activator.CreateInstance(targetType) : null;

 return ReadValue<object>(value) ?? defaultValue;

}

Jacob

# re: Non-generic default values in C#? Why not?!@ Sunday, October 01, 2006 2:39 PM

Thanxs for snippet

Rene Dohan

# re: Non-generic default values in C#? Why not?!@ Friday, February 08, 2008 6:52 AM

Resume, mister, which the best solution about this issue ? Greetings

espinete

# re: Non-generic default values in C#? Why not?!@ Tuesday, February 12, 2008 10:22 AM

Thank Man, That is cool trick for default initialization of object in generic.

Amber

# re: Non-generic default values in C#? Why not?!@ Friday, March 21, 2008 7:12 AM

The is the best solution I have seen to create default value of dynamic type.  Awesome!

Jason

# re: Non-generic default values in C#? Why not?!@ Wednesday, June 18, 2008 11:36 PM

Very nice solution,

Thanks for sharing.

Miron

Leave a Comment

(required) 
(required) 
(optional)
(required)