8

I saw this code block when i was trying build something with APN. Could someone explain me what does "this" statements do there ?

public ApplePushService(IPushChannelFactory pushChannelFactory, ApplePushChannelSettings channelSettings)
        : this(pushChannelFactory, channelSettings, default(IPushServiceSettings))

Is it like default values of those arguments ?

svick
  • 236,525
  • 50
  • 385
  • 514
paroxit
  • 627
  • 2
  • 12
  • 30
  • @dasblinkenlight though its related, thats not a duplicate of this question as far as intent goes. – nawfal May 31 '13 at 16:41
  • Also see http://stackoverflow.com/questions/3797528/base-and-this-constructors-best-practices – nawfal May 31 '13 at 16:51

3 Answers3

9

this calls the overloaded constructor for the ApplePushService class with the specified parameters.

For example

// Set a default value for arg2 without having to call that constructor
public class A(int arg1) : this(arg1, 1) 
{
}

public class A(int arg1, int arg2)
{
}

This lets you call one constructor that can invoke another.

Brandon
  • 68,708
  • 30
  • 194
  • 223
  • Are there any benefits of doing this rather than having optional parameters? –  May 31 '13 at 16:37
  • 2
    @MarkusMeskanen Optional parameters were not always supported by the language, and this also allows you to have a different order or omit parameters in between. Also you can easily use this to expand the constructor (e.g. in the example above, the two-parameter-constructor could also call `this(arg1)` and then do something special for the second parameter). – poke May 31 '13 at 16:44
9

Sure - that chains one constructor onto another. There are two forms - this to chain onto another constructor in the same class, and base to chain to another constructor in the base class. The body of the constructor you're chaining to executes, and then your constructor body executes. (Of course, the other constructor may chain onto another one first.)

If you don't specify anything, it automatically chains to a parameterless constructor in the base class. So:

public Foo(int x)
{
    // Presumably use x here
}

is equivalent to

public Foo(int x) : base()
{
    // Presumably use x here
}

Note that instance variable initializers are executed before the other constructor is called.

Surprisingly, the C# compiler doesn't detect if you end up with mutual recursion - so this code is valid, but will end up with a stack overflow:

public class Broken
{
    public Broken() : this("Whoops")
    {
    }

    public Broken(string error) : this()
    {
    }
}

(It does prevent you chaining onto the exact same constructor signature, however.)

For more details, see my article on constructor chaining.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

That is calling another constructor in that case, the : this(...) is used to call another constructor in that class.

For example:

public ClassName() : this("abc") { }

public ClassName(string name) { }

EDIT:

Is it like default values of those arguments ?

It an overload you can delegate it's full logic in one place and call from the rest of the constructors with default values.

this keyword can be used in these contexts:

  • Call other constructors.
  • Passing the current object as a parameter.
  • Refer to instance methods or fields.
Esteban
  • 3,108
  • 3
  • 32
  • 51