簡體   English   中英

單步執行程序時,無故調用ToString()方法

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

這是一個奇怪的問題,我旁邊的高級程序員也感到困惑。 完整的問題是,以某種方式調用了我的ToString()方法,我不知道或不知道這是我的代碼如何

static void Main(string[] args)
{
    Console.Out.WriteLine("Blank Constructor");
    Form form = new Form(); <-- ToString() gets called on this line.
    form.ToString();

    Console.Read();
 }

public Form()
{
    FormName = "";
    FormImageLocation = "";
    FormDescription = "";

    FormID = 0;

    CreatedDate = DateTime.Now;
    LastUpdate = DateTime.Now;

    Fields = new List<Field>();
    Packets = new List<Packet>(); <-- This line in the constructor
}

public override string ToString()
{
    string returnString;
    returnString = " Form Name: " +  FormName + " Form Image Location: " + FormImageLocation + "Form     Description: " + FormDescription + " FormID: " + FormID  + " Created Date: " + CreatedDate + "           LastUpdate: " + LastUpdate ;

    if (fields.Count != 0)
    {
        foreach (var field in fields)
        {
            returnString += field.ToString();
        }
    }
    else
    {
        returnString += "!!! This Form has no Fields !!!";
    }

    if (Packets.Count != 0)
    {
        foreach (var packet in Packets)
        {
            returnString += packet.ToString();
        }
    }
    else
    {
        returnString += " !!! This Form does not belong to any Packets !!!";
    }

    Console.Out.WriteLine(returnString);
    return returnString;
}

public Packet(string packet_name, List<Form> list_of_forms)
{
    PacketName = packet_name;
    forms = list_of_forms;
}

僅當我逐步執行程序時,才會出現ToString()打印的這種看似隨機的重復。 它會在我上面指定的行上打印,並且在構造函數退出並在我逐步遍歷ToString()方法本身時瘋狂打印時也會打印。 我在ToString()放置了一個斷點,但只有在合法調用ToString()時,它才會在斷點處停止,因此請注意,當我逐步執行並進行此隨機打印時,它不會在斷點內停止ToString() 我經過並刪除了對ToString()所有調用,當我注釋了returnString變量並僅返回“她在那里”時,它仍然被隨機調用,問題消失了,但這無濟於事。 如果我只運行沒有斷點的程序,則不會發生此問題。 你們中的有些人可能會說,如果在運行時可以正常運行,沒關系,但是這讓我非常警惕,如果我遇到了一個代碼問題,而我會嘗試逐步檢查代碼以發現問題,那么我會得到不同的結果並妨礙調試。 我嘗試涵蓋整個問題以及我嘗試過的內容並提供所有需要的代碼,如果我不清楚讓我知道的事情,我將嘗試再次進行解釋。 最后,我在Windows 7 64位計算機上,並且使用的是Visual Studio C#2010 Express。

您可能在表單上有一塊手表,或者以其他方式在調試器中顯示它的值(通過“ locals”窗口,堆棧跟蹤等)。 調試器使用ToString來顯示對象。 如果這是程序中的問題,則應該重新設計ToString這樣調用它就不會有問題,或者只是避免使用調試器。

通常要避免使用非常“昂貴”的ToString是一種需要警惕的情況。 有時可能會有例外,但確實如此,但呼叫者通常希望它是廉價的操作。 考慮是否有一些其他的方法/屬性來代表顯示字符串,而該方法/屬性涉及更多的內容,而留下一個更簡單/更便宜的ToString實現是否合適。

如果您觀看調試器,或者只是將鼠標懸停在對象上,調試器可能會調用ToString。 通常,將ToString中的副作用保持在最低限度是一個好主意。 即ToString不應引起任何狀態更改。

如果您觀看屬性並且get方法具有副作用,則會發生類似的問題。

另一個問題是使用LINQ時,因為調試器可能會評估從LINQ表達式返回的IEnumerable,這可能會引起各種副作用。 使用LINQ可能會變得更加棘手。 如果您有一些代碼實際上依賴於重新評估LINQ表達式的代碼(例如,某些代碼輪詢某些LINQ表達式,直到某些條件成立),那么在調試時您可能會遇到一些麻煩,因為調試器可能會緩存該表達式而不會重新-如您所願進行評估。

另一個類似的調試噩夢:調試焦點事件。 這很困難,因為激活調試器將失去焦點並產生副作用。 有時,良好的老式打印語句是最佳選擇。

我認為為了在Form()中顯示那些DateTime,當您嘗試實例化新的Form()時,調試器將在它們上調用ToString()...如@Servy所述

由於在Form()類中使用的不僅僅是字符串,因此必須調用ToString()以在您設置用於調試的停止點上顯示本地語言,並且需要相應地使用DebuggerDisplayAttribute或更改方式您正在重寫ToString()。

MSDN參考

就像其他人提到的那樣,調試器將調用ToString在多個位置可視化您的類。 這包括自動,本地和監視窗口。 如果您不希望調試器調用ToString,或者不想在連接調試器時發生短路,則可以選擇幾種方法。

DebuggerDisplayAttributeDebuggerTypeProxyAttribute

您可以將這兩個屬性之一添加到類定義中。 在調試器中運行時,它將獲取這些屬性,並使用這些屬性提供的替代方法或格式字符串代替您的ToString()方法。 下面顯示了表單Title屬性。

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

}

Debugger.IsAttached

您還可以在ToString方法的開頭檢查Debugger.IsAttached屬性,並實現替代行為。

    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
    }

將ToString()函數的名稱更改為其他

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM