2014年7月2日 星期三

[C#]Debugger會呼叫ToString()的問題

為了紀念一下我逝去的青春小鳥(浪費了我一整個下午)

來紀錄一下這次遇到的事件

簡單說我寫了一個組合SQL字串的class

其中裡面有InsertString、DeleteString、UpdateString、WhereString等StringBuilder的物件紀錄執行的動作

當中我override ToString()這個來自System.Object的方法

來輸出組合並輸出的字串

詭異的事情就此發生

在Visual Studio偵錯模式底下執行看程式變化時

有用過的人應該知道可以按F10或F11一步一步執行

其中你游標指到變數還可以看到變數的內容

後來我發現每指向變數一次變數(StringBuilder)的內容就會改變一次

而且用ToString()輸出後的確是有改變

之後我嘗試在ToString()中回傳前指派InsertString、DeleteString、UpdateString、WhereString都為null

沒想到居然會發生參照未指定物件的錯誤

但問題是我根本還沒呼叫ToString()這個方法

怎麼「看起來」好像有去呼叫ToString()

難道是我學藝不精?還是C#有什麼神奇魔力…?

找了半天也跟別人討論

最後才發現這個不曉得算不算bug的問題來源

一般偵錯模式底下執行時我們游標指到變數會顯示的是這個物件完整的class name

但其實這個內容是呼叫ToString()來的

可是ToString()又已經被我Override過了

所以就會發生我遇到明明沒呼叫ToString()卻會執行ToString()內容的靈異事件了

這個問題好像一直到Visual Studio 2012都還有

難道微軟不認為這是bug嗎?

後來我有嘗試方法用new但還是不行

他看來就是一定會去執行這個物件的ToString()不管你是override還是new

看起來他並非去copy出一個新物件

再去呼叫這個新物件的ToString()

所以要解決這個問題你只能取別的名字避免他莫名其妙偷偷去呼叫ToString()

可以參考以下兩篇也是苦主的文章

http://mocheng.wordpress.com/2009/06/06/%E5%88%AB%E8%AE%A9tostring%E5%87%BD%E6%95%B0%E6%94%B9%E5%8F%98%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%8A%B6%E6%80%81/
http://www.xuebuyuan.com/130963.html

沒有留言:

張貼留言