7

During an research the purpose of this reassignment possibility with structs I ran into following puzzle: Why it is needed to do this = default(...) at the beginning of some struct constructor. It's actually zeroes already zeroed memory, isn't it?

See an example from .NET core:

public CancellationToken(bool canceled)
{
    this = default(CancellationToken);
    if (canceled)
    {
        this.m_source = CancellationTokenSource.InternalGetStaticSource(canceled);
    }
}
Eugene D. Gubenkov
  • 5,127
  • 6
  • 39
  • 71
  • 2
    possible duplicate of [C# Structs "this = ...."](http://stackoverflow.com/questions/9648939/c-sharp-structs-this). Already answered by _big_ Jon. – Adriano Repetti Feb 20 '14 at 07:58
  • 2
    @Adriano: Jon doesn't say anything there about initializing a struct with `default()` of itself in its own constructor. – BoltClock Feb 20 '14 at 07:59
  • 2
    @Adriano What r u talking about? –  Feb 20 '14 at 08:00
  • @BoltClock IMO the _quotation mark_ in this question is `this` assignment itself, what `default()` does shouldn't be an issue. – Adriano Repetti Feb 20 '14 at 08:01
  • @Adriano: Fair enough. FWIW, there appears to be a more similar question based on what seems to be a different version of the source of this particular struct, which uses `new` rather than `default` to reassign - http://stackoverflow.com/questions/5562908/assignment-of-a-struct-value-to-this-keyword – BoltClock Feb 20 '14 at 08:04
  • @Adriano, Jon explains what does this = ... expression mean, but I don't see any hints to understand the purpose of this trick at the beginning of struct constructor – Eugene D. Gubenkov Feb 20 '14 at 08:06
  • possible duplicate of [What does default(object); do in C#?](http://stackoverflow.com/questions/2432909/what-does-defaultobject-do-in-c) – MCollard Feb 20 '14 at 08:06
  • Definitely not a question as to the purpose of `default(T)`. Still, it's my first time seeing this. I usually make my custom constructor call the `this()` constructor and all is well. – Daniel B Feb 20 '14 at 08:09

2 Answers2

11

It's actually zeroes already zeroed memory, isn't it?

No. When you create custom constructor for struct, it's your responsibility to set each and every field of struct to some value.

Just default .ctor() will fill it with zeroes - and that's one of the reasons why you are not allowed to implement own default .ctor for struct in C# (while CLR technically allows it, but it's a different topic to discuss).

So technique here is to call default(), which will create separate instance filled with zeroes, when using 'this = ' assignment will copy all fields from right to left (as it is struct), which will satisfy you need to initialize every field of struct. Then, you can do whatever you want.

In most cases it might be better (from code readability) to use something like this instead:

public MyStruct(..) : this() {
...
}
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Lanorkin
  • 7,310
  • 2
  • 42
  • 60
4

It's meeting a requirement for struct constructors:

If the struct instance constructor doesn’t specify a constructor initializer, the this variable corresponds to an out parameter of the struct type, and similar to an out parameter, this must be definitely assigned (§5.3) at every location where the constructor returns

C# Language Spec, Version 5, section 11.3.8

Of course, it doesn't have to be default() - it could be anything. But this must be assigned.


The rules for definite assignment (from section 5.3 referenced above) say, in part:

The definite assignment states of instance variables of a struct-type variable are tracked individually as well as collectively. In additional to the rules above, the following rules apply to struct-type variables and their instance variables:

  • An instance variable is considered definitely assigned if its containing struct-type variable is considered definitely assigned.
  • A struct-type variable is considered definitely assigned if each of its instance variables is considered definitely assigned.
Community
  • 1
  • 1
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • Do you want to say that every struct constructor must do this assignment? It's not true, just check e.g. Guid or DateTime implementation. – Eugene D. Gubenkov Feb 20 '14 at 08:11
  • @EugeneD.Gubenkov - just updated. It's meeting the requirement that `this` must be assigned. It doesn't have to be done with `default()`. – Damien_The_Unbeliever Feb 20 '14 at 08:12
  • @EugeneD.Gubenkov - also, the `Guid` and `DateTime` constructors that don't perform this type of assignment are taking advantage of the second bullet from the definite assignment rules I've added. Whereas the constructor you're looking at doesn't always assign to `m_source`. – Damien_The_Unbeliever Feb 20 '14 at 08:17