The C# „this“ keyword – what is it & how to use it?

The C# this keyword - what is it and how to use it
The C# this keyword – what is it and how to use it

What is the C# „this“ keyword?

You can „translate“ or treat the „this“ keyword in C# as some sort of „self referencing“ word like „me“ / „my“ in the first place. Next to this name qualifying feature, there are many more usecases like passing objects, creating indexers and more. Let’s dive a bit deeper to actually understand what the „this“ keyword exactly means.

infoIn a rush? I gotchu! I would highly recommend using the table of contents to navigate to your points of interest quickly!

To understand that „me“ portion better, we will evaluate on how this actually affects like designing our objects in our object oriented programming language C#. The easiest and probably most often used scenario for a „this“ keyword is to assign passed values (in e. g. a constructor) to fields and / or properties. We will take a more detailed look at that inside of the „How to use the this keyword in C#“ section of this blog post.

You could also for example have a customer paying for something like a bill or a product. There could be something like a „friendly customer“ and (sadly) a „bad mooded customer“. Both share a common behaviour we could name „Pay“, but the „friendly customer“ obviously does this somehow different than the „bad mooded customer“.

However both customers share a common base behind that payment process – both will pick their wallet (or credit card, but let’s stay easy here..) and start to pay. Please refer to the section mentioned above for the practical part of these two examples.

How to use the „this“ keyword in C#?

How to use the C# this keyword
How to use the C# this keyword

When writing software considering an object oriented programming approach you pretty much work with – objects – right? These objects mostly act together at our developers will and in vast different ways. As already mentioned above, there can be different scenarios where the „this“ keyword could be used in C# – let me show you some of those scenarios.

In a method with passed values (e. g. a constructor)

Let’s now start with the first practical example from above – the „passing values“ approach in for example a constructor or similar „method“. I mean a constructor is pretty much no different than a method – but this is another topic.

As you will see in the following little code snippet, I defined a small class called „Customer“ which offers two properties called „FirstName“ and „LastName“ obviously being strings. You can then see, that we’re requiring two parameters / arguments for the corresponding properties which need to be passed. Yes, I excluded something like „a customer could also be a business customer blabla company name“ stuff on purpose.

While retrieving the passed arguments inside the constructor body itself, we will forward those „values“ to their corresponding properties saying: „Hey, MY FirstName gets the value passed in by the argument firstName and MY LastName should get the value from the lastName argument“.

// define the class
public class Customer
{

  public string FirstName { get; set; }

  public string LastName{ get; set; }

  public Customer(string firstName, string lastName)
  {
    this.FirstName = firstName;
    this.LastName = lastName;
  }

}

// using the class
Customer customer = new Customer("John", "Doe");
Customer anotherCustomer = new Customer("Robert", "Skibbe");

The example from above actually doesn’t need the „this“ keyword, because we can distinguish the two „first name“ occurences by their capitalization. You could therefore just omit the „this.“ syntax. This is perfectly fine as you can easily avoid repetitive or „monkey work“ code by just having nice capitalization tactics.

Contrary to the above example, you actually would have to use the „this.“ syntax, if you had some code like the following. This time we manually implemented the properties instead of autoimplemented ones, so we actually have backing fields on the class level. Now the problem arises, that – inside of the constructor – we aren’t able to distinguish between the local variables / arguments and the class fields anymore. However we can easily fix that by using the „this.“ syntax now.

public class Customer
{

  // a private backing field!
  string firstName;

  // a manual getter / setter implementation
  public string FirstName
  {
    get => firstName;
    set => firstName = value;
  }

  // same for LastName...
  // ...
  // ...

  public Customer(string firstName, string lastName)
  {
    // now you would need to use this
    // as you couldn't distinguish between the
    // passed argument and the class field
    this.firstName = firstName;
    this.lastName = lastName;
  }

}

The approach used above here is actually called „qualifying members hidden by a similar name“.

Passing an object to other methods or properties

One of the next examples could be passing the reference of „yourself“ (the object) to different objects, methods, etc. Imagine our example from above actually had a class called „Wallet“. A wallet should have some sort of owner. Of course there could be different approaches of assigning this, but think about for example this following approach: A customer gets a wallet set and „he“ could say like „the wallet is mine now“. We could implement this inside of the setter of the customer class using the „this“ keyword!

public class Wallet
{

  public object Owner { get; set; }

}

// don't forget the customer class from above!
// I'm just extending here..

public class Customer
{
 
  Wallet _wallet;

  public Wallet Wallet
  {
    get => _wallet;
    set
    {
      _wallet = value;
      // this current customer is now the owner of the wallet!!
      _wallet.Owner = this;
    }
  }

}

// create a customer
Customer customer = new Customer();

// maybe somewhere later, button click, whatever
Wallet wallet = new Wallet();
// could be a method as well..
customer.Wallet = wallet;

This could be easily done with like a method as well. The customer can now have a method called „TakeWallet“ which obviously does two things: 1. The customer assigns the wallet instance to its Wallet property and 2. the wallet gets a new owner using the „this“ keyword!

public class Wallet
{

  public object Owner { get; set; }

}

public class Customer
{

  public Wallet Wallet { get; set; }

  public void TakeWallet(Wallet wallet)
  {
    // could also use "this.Wallet" but the "W" and "w"
    // already distinguish the different objects
    Wallet = wallet;
    // here it is - this!!
    wallet.Owner = this;
  }

}

Creating useful indexers for your classes

The next example is pretty useful for stuff like you might already know. I’m talking for example about the Dictionary class which is (and where it’s) already available. The dictionary gives you the opportunity to write something like in the following code example. We can use the indexer of the dictionary class to retrieve a value passing some sort of „key“:

// creating a simple phonebook
var myPhoneBook = new Dictionary<string, string>()
{
  {"robert", "12345"},
  {"carl", "67890"},
  {"jack", "11223"},
};

// getting carls number using an indexer!
string carlsNumber = myPhoneBook["carl"];

If you would want to write this all by yourself or something alike, you could easily do so by specifying a custom indexer for your class. I implemented this for example in a similar fashion when working on my free NuGet package called „rskibbe.I18n“. This way you can fetch translations and so on much easier. Please understand, that I cannot do a full guide on the indexing side right now, as this would be over the top for this blog post, but I will create a separate post for that in the future.

public class MyPhonebook
{

  Dictionary<string, string> _internalDic;

  public string this[string key]
  {
    get => _internalDic[key];
    set => _internalDic[key] = value;
  }

  public MyPhonebook()
  {
    _internalDic = new Dictionary<string, string>();
  }

  public MyPhonebook AddEntry()
  {
    // do some stuff
    return this;
  }

  // ....

}

Making methods chainable / returning the current object

Another possible usecase for the „this“ keyword in C# is for example using it as return value from a method. This is for example mostly used with things like chainable methods. Have a look at the following code snippet, then you will get the hang of it. We would usually call one method on the object on each line:

public class Phonebook
{

  public Phonebook AddEntry(string name, string phoneNumber)
  {
    // do some logic to add an entry
    // here, we are returning the CURRENT instance of the phonebook
    return this;
  }

}

var phonebook = new Phonebook();

// we could now add entries like this
// repeating "phonebook" over and over
phonebook.AddEntry("robert", "9876");
phonebook.AddEntry("carl", "5533");
phonebook.AddEntry("jack", "1234");

But we could actually chain those methods together. This is still „one method call per line“, but we don’t need to repeat the object instance over and over again:

var phonebook = new Phonebook();

// or we could NOW use method chaining
phonebook
  .AddEntry("robert", "9876")
  .AddEntry("carl", "5533")
  .AddEntry("jack", "1234");

Declaring extension methods

One of the next common examples for the usage of the „this“ keyword in C# could be the creation of extension methods. I won’t go too deep into extension methods here, as there will be a separate blog post, but generally speaking: Extension methods extend existing classes by providing new methods to them.

A typical extension method could look like this, as always, it’s just for displaying purposes. We could check existing integer for being even / odd. Notice the „this“ keyword inside the parameter declaration part!

public static class NumberExtensions
{

  public static bool IsEven(this int number)
  {
    return number % 2 == 0;
  }

}

We could now use the defined extension method like the following – but keep in mind, that you would need to watch for imports in a real scenario:

int myNumber = 2;
if (myNumber.IsEven())
{
  Console.WriteLine("The number is even, yay!");
} else {
  Console.WriteLine("Sadly, the number is odd!");
}

Passing parameters between constructors

Another typical example for the usage of the „this“ keyword is passing parameters / arguments between different constructor calls. I will explain it real quick! Take a look at the following class noticing that we have a pretty simple constructor which needs a difficulty level passed to it:

public class Dungeon
{
  
  public int Difficulty { get; set; }

  public Dungeon(int difficulty)
  {
    this.Difficulty = difficulty;
  }

}

Now imagine if you would want to create another for – example – constructor which doesn’t need an argument at all. For sure, you could simply use a default value for the first constructor, but then I couldn’t explain this scenario :)! In the next example I will use the „this“ keyword to call the „difficulty constructor“ from the empty constructor with the value 3.

public class Dungeon
{
  
  public int Difficulty { get; set; }

  public Dungeon() : this(3)
  {

  }

  public Dungeon(int difficulty)
  {
    this.Difficulty = difficulty;
  }

}

The above example can even work for chaining operations on the constructors. This means, that you actually call one constructor which calls another (like above), but the chain then continues and could call multiple more constructors after another.

Assigning a new value to this

There’s a pretty neat „feature“ for structs which most people actually don’t know. You can assign a new instance to the current instance by using „this“. Sounds confusing? Well it actually is in my opinion! But if after you saw it, you will probably easily get it. Take a look at the following code snippet where we will create a little „Reset“ functionality. Keep in mind – again – that it’s only for displaying purposes and you can’t use this with classes! Just for playing reasons, try to change „struct“ to „class“ and it won’t work anymore!

public struct Coordinates
{

  public int X { get; set; }

  public int Y { get; set; }

  public void Reset()
  {
    this = new Coordinates();
  }

}

Typecasting the current instance to another type

The following example usage of the „this“ keyword in C# could be being able to cast the current object instance to another type. For sure, this will only work if you made a correct inheritance hierarchy! Take a look at this where I created a base class called „Fruit“ and two other classes which inherit from it. If you have an instance of for example an apple, you could now cast itself to the base type using this here. For sure we could just substitute here, but just take a look at the „this“ keyword here – just as an example.

public class Fruit { /* ... */ }

public class Banana : Fruit { /* ... */ }

public class Apple : Fruit
{

  public Fruit SomeMethod()
  {
    // could / should be done anyways
    // Liskov Substitution Principle etc..
    // but just take it as an example
    return (Fruit) this;
  }

}

Apple apple = new Apple();
Fruit appleFruit = apple.SomeMethod();

When you should / shouldn’t use the „this“ keyword?

When and when not to use the C# this keyword
When and when not to use the C# this keyword

Next to the examples from above there will be situations where you should potentially avoid – or even prefer – the usage of the „this“ keyword. Right at the beginning of the post I showed an easy fix to easily avoid using the „this“ keyword by just using a nice capitalization for your arguments and fields.

I’m a personal fan of „only use things if they are necessary“ to keep my code as „clean“ and small as possible. I personally don’t want to repeat myself over and over again by using the „this.“ syntax as it’s pretty annoying. Some developers prefer that style because it can support finding the origin / scope of a variable in their opinion.

infoI mean as mostly in terms of development – take some arguments with a grain of salt, as every team and even every developer himself could see this totally different. Constancy is most important.

However even then I would prefer my approach, because if you stick to the .NET code guidelines, your protected and private variables should be named with an underscore anyways, so I instantly know where the variables are coming from. Sadly I couldn’t find the MSDN link right now, but I will supplement that as soon as I find it. The most important thing is that you and / or your team should stick to one naming ruleset anyways.

More

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert