C# struct new StructType() vs default(StructType)

C#Struct

C# Problem Overview


Say I have a struct

public struct Foo
{
    ...
}

Is there any difference between

Foo foo = new Foo();

and

Foo foo = default(Foo);

?

C# Solutions


Solution 1 - C#

You might wonder why, if they are exactly the same, there are two ways to do the same thing.

They are not quite the same because every reference type or value type is guaranteed to have a default value but not every reference type is guaranteed to have a parameterless constructor:

static T MakeDefault<T>()
{
    return default(T); // legal
    // return new T(); // illegal
}

Solution 2 - C#

No, both expressions will yield the same exact result.

Since structs cannot contain explicit parameterless constructors (i.e. you cannot define one yourself) the default constructor will give you a version of the struct with all values zero'd out. This is the same behavior that default gives you as well.

Solution 3 - C#

The language specification (§4.1.2 and §5.2) is your friend. Specifically:

>For a variable of a value-type, the default value is the same as the value computed by the value-type’s default constructor (§4.1.2).

(Italics in original.)

Note that this is not the same for reference types.

>For a variable of a reference-type, the default value is null.

This is emphatically different than the value produced by a default constructor, if one exists.

Solution 4 - C#

For value-types, the options are, practically speaking, equivalent.

However, I was intrigued by Jon Skeet's empirical research into which 'instructions' result in the invocation of a struct's parameterless default constructor when it is specified in CIL (you can't do it in C# because it doesn't let you). Amongst other things, he'd tried out default(T) and new T() where T is a type parameter. They appeared equivalent; neither of them appeared to call the constructor.

But the one case (it appears) he hadn't tried was default(Foo) where Foo is an actual struct type.

So I took his code for the 'hacked' struct and tried that out for myself.


It turns out that default(Foo) doesn't call the constructor, whereas new Foo() in fact does.

Using a struct type Oddity that specifies a parameterless constructor:

With optimizations turned off, the method:

private void CallDefault()
{
    Oddity a = default(Oddity);
}

produces the CIL (without nops, rets etc.):

L_0001: ldloca.s a
L_0003: initobj [Oddity]Oddity

whereas the method:

private void CallNew()
{
    Oddity b = new Oddity();
}

produces:

L_0001: ldloca.s b
L_0003: call instance void [Oddity]Oddity::.ctor()

With optimizations turned on, the compiler appears to optimize away pretty much all of the CallDefault method into a no-op, but keeps the call to the constructor in CallNew (for potential side-effects?).

Solution 5 - C#

default keyword is useful when you do not know exact type and it works not only for structs, for example in generics:

T FirstOrDefault(IEnumerable<T> source)
{
    if (...source is empty...) return default(T);
}

This will return null for reference types, default value for primitive types(0 for numbers, false for bool), defaultly inialized structure, etc ...

When type is known at compile-time it makes no sense to use default, you can use new Foo() instead

Solution 6 - C#

Small update with the freshly (C# 10) introduced Parameterless constructors and field initializers. default(MyStruct) and new MyStruct are not the same anymore.

new MyStruct().PrintToConsole();    // Prints 10
default(MyStruct).PrintToConsole(); // Prints 0

public struct MyStruct
{
	private int anyNumber;
	
	public MyStruct()
	{
		anyNumber = 10;
	}
	
	public void PrintToConsole() => System.Console.WriteLine($"My number is: {anyNumber}");
}

If you want to fiddle around on your own here you go

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBala RView Question on Stackoverflow
Solution 1 - C#Eric LippertView Answer on Stackoverflow
Solution 2 - C#Andrew HareView Answer on Stackoverflow
Solution 3 - C#jasonView Answer on Stackoverflow
Solution 4 - C#AniView Answer on Stackoverflow
Solution 5 - C#SnowbearView Answer on Stackoverflow
Solution 6 - C#LinkView Answer on Stackoverflow