web-dev-qa-db-ja.com

構造体/クラスの初期化メンバーをメンバーごとにデバッグすることは可能ですか?

このようなクラスを初期化する:

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

割り当ての1つでInvalidCastExceptionが発生します。かなりたくさんあり、デバッガーを1行ずつ実行しても、式全体で例外が発生します。例外は、何にキャストしようとしているかの手掛かりも与えません。

各割り当てを個別にデバッグする方法はありますか?デバッガーがforeach(x in y)のような式で個別に3回停止するのを確認したので、ここでそれを行わないのは少し奇妙に思われ、この便利な初期化構文を使用する魅力が損なわれます。多分私が使用できるよりきめの細かいデバッグ手順がありますか?

5
Mr. Boy

何か不足している場合は失礼します(その場合は削除されます)が、次のような無効なキャストを使用しています。

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

ただし、これは最初のエラーで中断します。この方法でオブジェクトを初期化し、初期化を終了せずにすべてのキャストエラーをログに記録したい場合があります。これを行うには、このサンプルに独自のキャストを実装します。

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; }
    }

その後、次のようにオブジェクトを初期化できます。

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"
            };

また、キャスト時に発生する可能性のあるエラーをきちんと記録します。

Result in the console

0