3

I'm trying to override method ToString() to return value of a field in my class and clear that field (return value only once). I've noticed that the code seems to work when I'm running it without any interruption to the end (at least pass the overriden method), but when debugging step-by-step it returns no value, and it looks like there is no value stored at the init of the object.

I've managed to fix this issue by changing the name of the method from ToString() to other not overrided name, also commenting the line text = ""; makes it work, but I don't know why. The same was happening when I tried to assign a StringBuilder value to temp var, clear StringBuilder and return temp value. I'm curious what causes that strange behavior.

class Program
{
    public class MyClass
    {
        private string text = "some value";
        public override string ToString()
        {
            string temp = text;
            text = "";
            return temp;
        }
    }
    public class MyClass2
    {
        private string text = "some value";
        public override string ToString()
        {
            return text;
        }
    }
    static void Main(string[] args)
    {
        MyClass obj = new MyClass();
        MyClass2 obj2 = new MyClass2();

        Console.WriteLine("1 MyClass: " + obj.ToString());
        Console.WriteLine("1 MyClass2: " + obj2.ToString());

        Console.WriteLine("2 MyClass: " + obj.ToString());
        Console.WriteLine("2 MyClass2: " + obj2.ToString());

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

When I run the code to the ReadKey(); without interrupts the output is:

1 MyClass: some value
1 MyClass2: some value
2 MyClass:
2 MyClass2: some value
Press any key to exit

When stepping through the code with F10 the output is:

1 MyClass:
1 MyClass2: some value
2 MyClass:
2 MyClass2: some value
Press any key to exit
5
  • 6
    That seems a very odd and potentially quite confusing use of ToString() Commented Jun 7, 2019 at 13:05
  • 2
    ToString should not have side-effects. Commented Jun 7, 2019 at 13:11
  • Certain methods have specific purpose and should NOT be used to change state. Since you are calling ToString() anyway just create a method with better name, e.g. GetStringAndReset(). Commented Jun 7, 2019 at 13:13
  • If its for debugging i often use debuggerdisplayattribute learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/… Commented Jun 7, 2019 at 13:15
  • See stackoverflow.com/questions/20980503/… . Commented Jun 7, 2019 at 13:18

2 Answers 2

5

What you actually see is the result of evaluation by the IDE, in your case Visual Studio. It seems Visual Studio loaded the instance in the Locals view, and determined its value by calling ToString, thus by your logic changing the variables. (Quite a lot of other reasons VS evaluated this method are possible, but this seems the most likely one to me.)

It is very dangerous to rely on side effects on the ToString method, as you have experienced. If you want reliable code, use some other property or method.

Sign up to request clarification or add additional context in comments.

1 Comment

It looks like You're right, in locals view there is a list of object variables and a whole object value that shows whatever ToString() method returns. I've also noticed that when VS calls that method it doesn't hit a breakpoint if there is one set in ToString() method (for obvious reasons) and that's what misled me. Thanks :)
1

It is happening because everytime you move your mouse over the object, it executes the ToString method to give you something to view.

In the second execution of that method, your object loses string's value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.