2

In VBA, I constantly passed class instances as parameters to their own methods if I was going to be modifying their property values. To give an extremely simplified C# example:

class WhateverClass
{
    public void DoSomething(WhateverClass whateverClass)
    {
        whateverClass.WhateverProperty = "Hello"
    }
}

In C#, can I avoid needing to pass called class instances as parameters by using this, like so? Or will this refer to the default class instance?

class WhateverClass
{
    public void DoSomething()
    {
        this.WhateverProperty = "Hello"
    }
}
puzzlepiece87
  • 1,537
  • 2
  • 19
  • 36
  • To be clear, you could have done the exact same thing in VBA. There was no need to pass the instance to its own method in VBA, or C#. – mjwills Oct 31 '19 at 21:51
  • 4
    There is no such thing as a "default class instance". – Rufus L Oct 31 '19 at 21:51
  • @RufusL I was also confused about that. Maybe he thougt that is what "this" in VB does? – Christopher Oct 31 '19 at 21:52
  • 3
    VBA / VB 6 (and apparently VB.NET) had a concept roughly equivalent to that @RufusL with forms specifically. So if a form was called `Form1` then you could use `Form1` without newing it up. It didn't apply outside of forms though. _It was also a nightmare in practice._ – mjwills Oct 31 '19 at 21:54
  • @RufusL Maybe he refers to this thing? https://stackoverflow.com/questions/4698538/why-is-there-a-default-instance-of-every-form-in-vb-net-but-not-in-c – Christopher Oct 31 '19 at 21:54
  • @RufusL Christopher mjwills You are all exactly right. I saw default instancing of forms in VBA and thought it applied to classes as well. I just tested it out in VBA and you are correct that there's no default class instance. I've been doing a lot of unnecessary work this year lol. – puzzlepiece87 Oct 31 '19 at 22:04
  • @puzzlepiece87 Default instances are a _very_ bad practice, and one of the most annoying features of VB. Try to avoid using them - ever. – mjwills Oct 31 '19 at 22:06
  • 3
    @mjwills I completely agree, that's why I was so fastidious about unnecessarily passing calling instances as a parameter, because I was trying to steadfastly avoid that issue. – puzzlepiece87 Oct 31 '19 at 22:09
  • 1
    Just to clarify things on the VBA / VB6 side. Whether a class/form has a default instance is determined by the value of the attribute `VB_PredeclaredId`. For forms, it defaults to `True` and for other classes to `False`. However, it can be changed by manipulating exported code and reimporting it. – M.Doerner Oct 31 '19 at 22:36
  • 1
    @mjwills *stateful* default instances are evil/annoying. Just like `static` state in C#. Default instances in VBA are extremely useful to implement e.g. factory methods. Used judiciously, default instances are a tool, like `static` methods are in C#. Whether they're misused and abused doesn't take away their usefulness! – Mathieu Guindon Nov 01 '19 at 00:02
  • @M.Doerner Mathieu Guindon Thanks for correcting us on that! – puzzlepiece87 Nov 01 '19 at 15:12

2 Answers2

3

this refers to the called class instance.

I made the following test app to check:

class Program
{
    static void Main()
    {
        var class1 = new Class1();
        class1.Setup();

        Console.Write(class1.Property1);
        Console.ReadKey();
    }
}


class Class1
{
    public string Property1 { get; set;}

    public Class1 ()
    {
        this.Property1 = "Overwrite me";
    }


    public void Setup()
    {
        this.Property1 = "Successfully overwritten";
    }
}

The output of this was "Successfully overwritten"

puzzlepiece87
  • 1,537
  • 2
  • 19
  • 36
  • A bit of pedantry --- you said `calling class instance` but this is the `called class instance`. `Program` would be the calling class that invoked a method on `class1`, which is the called class instance of type `Class1`. – this Nov 01 '19 at 15:52
  • @this Thanks for helping me tighten that up! I definitely want to be able to communicate both of those concepts effectively. – puzzlepiece87 Nov 01 '19 at 15:54
2

It refers to the instance, the method is called on.

DoSomething is non-static, so it has to be called on a instance.

A interesting case is "this" as used in extension methods. Extension methods are little more then syntactic sugar for static functions, which have to be called on a class instance. In that case, it is annotating the 1st Parameter, which will automagically be the instance it is called upon.

puzzlepiece87
  • 1,537
  • 2
  • 19
  • 36
Christopher
  • 9,634
  • 2
  • 17
  • 31