Reputation: 475
Let's say we have these two structs...
public struct Example
{
public int Number { get; set; }
public Example(int Number)
{
Number = number;
}
}
and:
public struct Example
{
public int Number { get; set; }
public Example(int number) : this()
{
Number = number;
}
}
You can see that there's a struct with a constructor with **this()**
at the end and another without.
What is the difference between the two?
Upvotes: 4
Views: 337
Reputation: 3235
Calling this() initializes all fields with zeroes. C# compiler requires all struct fields to be initialized in constructor. So if you want to specify not all fields you should call this().
Will not compile:
struct A
{
public int field1;
public string field2;
public A(string str)
{
field2 = str;
}
}
Gives:
Error CS0171 Field 'A.field1' must be fully assigned before control is returned to the caller ...
Is OK:
struct A
{
public int field1;
public string field2;
public A(string str) : this()
{
field2 = str;
}
}
Weird, but still OK:
struct A
{
public int field1;
public string field2;
public A(string str)
{
this = new A(); // in structs 'this' is assignable
field2 = str;
}
}
or
struct A
{
public int field1;
public string field2;
public A(string str)
{
this = default(A); // in structs 'this' is assignable
field2 = str;
}
}
Upvotes: 6
Reputation: 1447
In your example, there is no behavioral change as this()
calls the parameter-less constructor for the struct which is not defined.
Note that in C# 6.0 and newer you cannot re-define a struct's parameter-less constructor, so if you do:
public struct Example
{
public Example() // compile error in c# 6.0 and up
{
}
}
You'll get a compile error. More details here.
In older versions of C# you can re-define the parameter-less constructor which means you may inject extra behavior in your parameterized constructor by modifying the parameter-less one.
Apart from this, there may be a theoretical performance hit due to the extra IL code generated for the this()
constructor:
Example..ctor:
IL_0000: ldarg.0
IL_0001: initobj UserQuery.Example
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000A: call UserQuery+Example.set_Number
IL_000F: nop
IL_0010: ret
Upvotes: 2
Reputation: 1204
UPDATED
For a class:
The difference is that the constructor that calls this()
will also call the class's constructor that takes no arguments. So, for example, if this were your class:
public class Example
{
public int Number { get; set; }
public Example(int number) : this()
{
Number = number;
}
public Example()
{
Console.WriteLine("Hello");
}
}
Then including this()
would also print "Hello". This is a way you can chain constructors together, for code reuse.
For a struct:
You cannot add an empty constructor in a struct, so adding this()
does not provide any benefit. Thanks to vendettamit for waking up my tired brain.
Upvotes: 2
Reputation: 4109
There is no difference. this()
would call to a parameterless constructor, which is a must for structs by definition, which will not do anything unless you redefine it and customize its behavior. In case of struct
s you are not allowed to define your own parameterless constructor; with class
es you can though.
However, please note that constructor chaining is a handy tool to DRY in a complicated construction scenarios: i.e. when object exposes numerous constructors with different parameters.
Upvotes: 1