web-dev-qa-db-fra.com

Est-il possible de déboguer un membre d'initialisation struct / class par membre?

Initialiser une classe comme celle-ci:

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

J'obtiens une InvalidCastException sur l'une des affectations. Il y en a beaucoup et l'exception se produit sur toute l'expression même si j'exécute le débogueur ligne par ligne. L'exception ne donne aucun indice non plus sur ce qu'elle essaie de convertir en quoi.

Existe-t-il un moyen de déboguer chaque affectation individuellement? J'ai vu le débogueur s'arrêter séparément 3 fois sur des expressions comme foreach(x in y) donc cela semble un peu étrange qu'il ne le fasse pas ici, et diminue l'attrait de l'utilisation de cette syntaxe d'initialisation pratique. Peut-être que je peux utiliser une étape de débogage plus fine?

5
Mr. Boy

Veuillez m'excuser si je manque quelque chose (supprimera si c'est le cas) mais en utilisant un casting invalide comme celui-ci:

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

attrape parfaitement l'erreur comme ceci Unable to cast object of type 'Base' to type 'Derived'. en vs2017

Cependant, cela casse sur la première erreur, nous pourrions vouloir initialiser un objet de cette façon et enregistrer toutes les erreurs de conversion sans quitter l'initialisation. Nous pouvons le faire en implémentant notre propre casting pour cet exemple:

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

Nouveaux types à des fins de démonstration

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

Nous pouvons alors initialiser notre objet comme ceci:

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

Et nous enregistrons soigneusement toutes les erreurs pouvant survenir lors de la diffusion:

Result in the console

0