Uses of “this” Keyword

2019-07-27 20:16发布

问题:

I'm studying the uses of this and I think I understand it, at least partially, like when to solve ambiguity and to call methods from the "current" class, but one example from the book I'm reading(Head First C#) is giving me a hard time:

public void SpeakTo(Elephant whoToTalkTo, string message) {
    whoToTalkTo.TellMe(message, this);
}

In this method, is it safe to say that the this has the function of always refering to whatever object calls the method SpeakTo(), regardless of which class the call is written in?

回答1:

In this method, is it safe to say that the "this" has the function of always refering to whatever object calls the method "SpeakTo()", regardless of which class the call is written in?

Nope. this does not refer to the object that calls SpeakTo. It refers to the object on which SpeakTo is called.

I will use some code to clarify this point

class Foo {
    public static void Main(String[] args) { 
        var foo = new Foo();
        foo.MyMethod();
    }

    public void MyMethod() {
         var bar = new Bar();
         bar.SpeakTo(anElephant, "Hello");
     }
}

class Bar {
    public void SpeakTo(Elephant whoToTalkTo, string message) {
       whoToTalkTo.TellMe(message, this);
    }
}

According to your statement, this refers to the foo variable that's created in the main method. This is not the case. this actually refers to bar. i.e. the object that's before the method name.



回答2:

No... Actually, this in your context refers to the object on which SpeakTo is defined, not the object which calls it.

Let's put it this way:

  • Object speaker is of the class Speaker which defines the SpeakTo method,
  • Object caller is calling the speaker.SpeakTo(), and
  • Object whoToTalkTo is of the class which defines the TellMe(string, Speaker)

As you can see, whoToTalkTo is expecting the Speaker class instance. Then, the speaker object is precisely that, and it is free to pass this as the argument.

Now we can construct a larger example in which these relations are becoming more obvious:

class Speaker
{
    public int Data { get; set; }

    public void SpeakTo(Elephant whoToTalkTo, string message) 
    {
        // Passing current instance of this class as the argument
        whoToTalkTo.TellMe(message, this);
    }
}

This Speaker class contains a piece of state. Now I will use the whoToTalkTo object to change that state:

class Talker
{
    public void TellMe(string message, Speaker speaker)
    {
        speaker.Data = message.Length;
    }
}

This implementation is changing the state of one particular object which was passed to it.

Now the ultimate caller comes to the picture, the one which actually selects the Speaker object which will be subjected to the TellMe() method:

class Caller
{
    public void DoWork()
    {
        Talker talker = new Talker();

        Speaker one = new Speaker();
        Speaker two = new Speaker();

        // This sets one.Data to length of "something"
        one.SpeakTo(talker, "something");

        // This sets two.Data to length of "else"
        two.SpeakTo(talker, "else");

        Console.WriteLine(one.Data);
        Console.WriteLine(two.Data);
    }
}

This code will print values 9 and 4, which indicates that the whoToTalkTo has actually been modifying the state of two distinct objects.



回答3:

this refers to the current object of the class which has method SpeakTo.

consider the following example:

public class A
{
      public void SpeakTo(Elephant whoToTalkTo, string message) {
          whoToTalkTo.TellMe(message, this);
       }
}

Now if you instantiate an object of A and calls the method SpeakTo it will be like:

A obj = new A();
obj.SpeakTo();

In the method SpeakTo, this refers to the current object, i.e. obj.

The signature of method TellMe should look like:

public void TellMe(string message, A objOfA)


标签: c# this