When stepping through my program the ToString() method is being called for no reason

浪子不回头ぞ 提交于 2019-11-29 16:10:19

You probably have a watch on the form, or are in some other way displaying it's value in the debugger (through the "locals" window, the stack trace, etc.). The debugger uses ToString to display objects. If this is a problem in your program, you should likely re-design your ToString such that it isn't a problem for it to be called like this, or else simply avoiding using the debugger.

Having a very "expensive" ToString that you generally wish to avoid using is a situation to be wary of. There can be occasional exceptions where it does make sense, but callers generally expect it to be a cheap operation. Consider whether or not it would be appropriate to have some other method/property representing a display string that is more involved, leaving a simpler/cheaper ToString implementation.

The debugger may call ToString if you watch it or even if you just hover the mouse over the object. Usually it is a good idea to keep side effects in ToString at a bare minimum. I.e. ToString should not cause any state change.

A similar problem occurs if you watch properties and the get method has side effects.

Another problem is when using LINQ, since the debugger may evaluate the IEnumerable returned from an LINQ expression, which may cause all sort of side effects. With LINQ it may get even more tricky. If you have some code that actually rely on the LINQ expression being reevaluated (say some code that polls some LINQ expression until some condition is true), then you can gain some gray hairs when debugging, since the debugger may cache the expression and not re-evaluate it as you expect.

Another similar debugging nightmare: Debugging focus events. Very hard to do, since activating the debugger will steal focus and cause side effects. Sometimes good old-fashion print statements are the best option.

I think that in order to display those DateTimes in Form(), the debugger is calling ToString() on them when you try to instantiate a new Form()... as @Servy has mentioned

Since you are using more than just strings in your Form() class, ToString() has to be called to display the locals in the stop point you've set for debugging and you'll need to use the DebuggerDisplayAttribute accordingly or change the way you're overriding ToString().

MSDN Ref

As mentioned by others, the debugger will call ToString to visualize your class in multiple locations. This includes the Autos, Locals and Watch windows. If you don't want the Debugger to call ToString, or want to short-circuit when the debugger is attached you have a few options.

DebuggerDisplayAttribute or DebuggerTypeProxyAttribute

You can add one of these two attributes to your Class definition. When running in the debugger it will pick up these attributes and use the alternative method or format string supplied by these attributes instead of your ToString() method. The following shows the forms Title property instead.

[DebuggerDisplay("MyForm under debugger {Title}")]
public class MyForm : Form
{

}

Debugger.IsAttached

You can also check the Debugger.IsAttached property at the start of your ToString method and implement alternative behavior.

    public override string ToString()
    {
#IF (DEBUG)
        if ( Debugger.IsAttached )
        {
            return this.GetType().Name + ": " + this.Title; // or something else.
        }
#ENDIF
        // The rest of your ToString implementation
    }

change the name of ToString() function to sth else

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!