Using this() in C# Constructors

Go To StackoverFlow.com

10

I have been trying to figure out if there are any differences between these constructors. Assuming there is a Foo() constructor that takes no arguments, are all these constructors going to have the same result?

Example 1

public Foo()
    : this()
{
     blah;
     blah;
     blah;
}

Example 2

public Foo()
{
     this();
     blah;
     blah;
     blah;
}

Example 3

public Foo()
{
     this = new Foo();
     blah;
     blah;
     blah;
}
2009-06-16 14:04
by Tim
+1 taught me something new with Example#3 n the fact that J S is always lurkin - Gishu 2009-06-16 14:24


32

  • Example 1 is valid (assuming there is a parameterless constructor), and calls the parameterless constructor as part of initialization. See my article on constructor chaining for more details. EDIT: Note that since the OP's edit, it's infinitely recursive.
  • Example 2 is never valid
  • Example 3 is only valid when Foo is a struct, and doesn't do anything useful.

I would steer clear of assigning to this in structs. As you can see from the other answers, the very possibility of it is fairly rarely known (I only know because of some weird situation where it turned up in the spec). Where you've got it, it doesn't do any good - and in other places it's likely to be mutating the struct, which is not a good idea. Structs should always be immutable :)

EDIT: Just to make people go "meep!" a little - assigning to this isn't quite the same as just chaining to another constructor, as you can do it in methods too:

using System;

public struct Foo
{
    // Readonly, so must be immutable, right?
    public readonly string x;

    public Foo(string x)
    {
        this.x = x;
    }

    public void EvilEvilEvil()
    {
        this = new Foo();
    }
}

public class Test
{
    static void Main()
    {
        Foo foo = new Foo("Test");
        Console.WriteLine(foo.x); // Prints "Test"
        foo.EvilEvilEvil();
        Console.WriteLine(foo.x); // Prints nothing
    }
}
2009-06-16 14:07
by Jon Skeet
I wasn't aware 3 was legal, but you're right, it is. I always accomplished the same thing by chaining the parameterless constructor - mquander 2009-06-16 14:08
I had always thought that : was used for inheritance - is there any inheritance happening in Example 1, or is this just an overloaded usage of the colon - Tim 2009-06-16 14:09
The colon just means something different in this context. Constructor chaining on MSDN: http://msdn.microsoft.com/en-us/library/ms173115.asp - mquander 2009-06-16 14:10
That example is quite remarkable. I'm very surprised that you can do such a thing - mquander 2009-06-16 14:14
Thanks for help everyone - Tim 2009-06-16 14:14
@mquander: Yes, it's thoroughly evil, isn't it? Ick - Jon Skeet 2009-06-16 14:19
Is this still assuming there is a parameterless constructor for Foo? If we defined a parameterless constructor that set x, wouldn't it behave as we would expect - Tim 2009-06-16 14:22
J S - you still the C# dude. But I wish I hadn't read that you can assign this to a new struct : - Gishu 2009-06-16 14:24
Well you learn something new every day - Dan Blair 2009-06-16 14:27
@Tim: This is a struct - you can't write your own parameterless constructor (in C#, anyway - you can in IL) - Jon Skeet 2009-06-16 14:39
Sorry to resurrect this thread. Isn't Example 1 effectively an infinitely recursive loop? I can see it working with :base() but not :this() - gnomed 2013-06-12 18:37
@gnomed: When I answered it, the constructor had a parameter. I don't know why the OP changed it significantly - Jon Skeet 2013-06-12 22:03
@JonSkeet Aha, oh well. Good to know. Sorry to drag up old topics, and thanks for getting back to me. PS: Just noticed, the OP actually works in my office and is sitting about 5 desks away from me right now (same user picture as his work skype).... the internet is freaking me out - gnomed 2013-06-12 22:27
@Jesse C. Slicer: Your edit made no sense... Foo is a type, so you don't declare the type of that. The original answer was made when there was a parameter called bar, with no specified type. It's fine to edit the answer because the question was changed, but please only edit it to something meaningful : - Jon Skeet 2013-06-13 07:41
@JonSkeet Sorry about that. I must have picked the wrong week to stop sniffing glue - Jesse C. Slicer 2013-06-13 21:53


11

Examples 2 and 3 are not legal C#.

EDIT: Jon points out accurately that 3 is legal when Foo is a struct. Go check out his answer!

2009-06-16 14:05
by mquander
>3 is used as a copy constructor struct Foo { int a; Foo(Foo other) { this=other; } } - ja72 2015-04-07 20:10


4

No they will not because only the first constructor is actually legal. The other two are illegal for various reasons.

EDIT Interesting, 3 is indeed legal when Foo is a struct. But even in that case, it is a redundant assignment.

2009-06-16 14:05
by JaredPar
Ads