簡體   English   中英

是否可以按成員調試結構/類初始化成員?

[英]Is it possible to debug a struct/class initialization member by member?

像這樣初始化 class :

var x = new Item()
{
 ID = (int)...,
 Name = (string)...,
 ..
};

我在其中一項作業中收到 InvalidCastException。 它們有很多,即使我逐行運行調試器,整個表達式也會出現異常。 該異常並沒有給出任何線索,也沒有給出它試圖投射到什么的任何線索。

有沒有辦法單獨調試每個作業? 我已經看到調試器在foreach(x in y)之類的表達式上分別停止了 3 次,所以在這里沒有這樣做似乎有點奇怪,並且降低了使用這種方便的初始化語法的吸引力。 也許我可以使用更細粒度的調試步驟?

您的問題是“是否可以按成員調試結構/類初始化成員?”。

所以,在前面,我沒有直接回答這個問題的措辭,因為當我仔細閱讀你的帖子的正文時,聽起來基本問題是如何在這個 InvalidCastException 發生時識別“吸煙線”的根本原因。

我在類似情況下發現的是,如果可以在 InvalidCastException 發生的那一刻(即在該特定行上)中斷 Visual Studio,那么調用堆棧和局部變量會更加直接和有用。

不幸的是,許多異常類型的 Visual Studio 默認設置抑制了“拋出時中斷”。 但是很容易為所有異常打開“拋出時中斷”。 只需在 Visual Studio 的 Exceptions window 中更改此默認設置:

默認例外設置

對此:

在此處輸入圖像描述

這並不“總是”有幫助,但它是一個好的開始。 這很容易,為什么不先嘗試一下,看看是否可以快速解決。 希望這對您的情況有用。

不確定這是否是 VS 2017 中的一個選項,我手頭只有 2019 年。 Options -> Debugging -> General下的設置中,取消選中Step over properties and operator 然后在初始化程序處設置一個斷點並使用 F11(Step-Into)單步執行。 您將點擊每個屬性設置器,直到拋出異常。

如果我遺漏了某些東西(如果是這種情況,將刪除)但使用這樣的無效演員表,請原諒:

struct Item
{
    public int ID { get; set; }
    public Derived Derived { get; set; }
}
public class Base
{
    public string Name { get; set; }
}
public class Derived : Base
{
    public string AdditionalProperty { get; set; }
}
var baseClass = new Base()
{
    Name = "foo",
};
try
{
    var x = new Item()
    {
          ID = (int)20,
          Derived = (Derived)baseClass,
    };
}
catch(Exception e)
{
          Console.WriteLine(e.Message);
}

巧妙地捕捉到這樣的錯誤Unable to cast object of type 'Base' to type 'Derived'. 在vs2017中

但是,這會在第一個錯誤時中斷,我們可能想以這種方式初始化 object 並在不退出初始化的情況下記錄所有轉換錯誤。 我們可以通過為此示例實現我們自己的轉換來做到這一點:

public static T TryCast<T>(Object _object)
        {
            try
            {
                return (T)_object;
            }
            catch (Exception e)
            {
                Console.WriteLine($"Cant cast object of type {_object.GetType().ToString()} to object of type {typeof(T)}");
            }
            return default(T);
        }
 public static T TryCast<T>(IConvertible _object)
        {
            try
            {
                return (T)Convert.ChangeType(_object, typeof(T));
            }
            catch (Exception e)
            {
                Console.WriteLine($"Cant convert object of type {_object.ToString()} to object of type {typeof(T)}");
            }
            return default(T);
        }

用於演示目的的新類型

struct Item
    {
        public int ID { get; set; }
        public double FooDouble { get; set; }
        public Base Base { get; set; }
        public Derived Derived { get; set; }
        public string Bar { get; set; }
    }
    public class Base
    {
        public string Name { get; set; }
    }
    public class Derived : Base
    {
        public string AdditionalProperty { get; set; }
    }

然后我們可以像這樣初始化我們的 object:

var derived = new Derived()
            {
                Name = "DerivedFoo",
                AdditionalProperty = "Bar"
            };
            var _base = new Base()
            {
                Name = "BaseFoo"
            };
            var x = new Item()
            {
                ID = Utils.TryCast<int>("please no"),
                FooDouble = Utils.TryCast<double>(2),
                Base = Utils.TryCast<Base>(derived),
                Derived = Utils.TryCast<Derived>(_base),
                Bar = "Foo"
            };

我們巧妙地記錄了投射時可能發生的任何錯誤:

結果在控制台

暫無
暫無

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

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