как решить System.Исключение StackOverflowException?

#c# #asp.net-core #asp.net-web-api #blazor #stack-overflow

#c# #asp.net-core #asp.net-web-api #блейзор #переполнение стека

Вопрос:

привет, сообщество, у меня есть product class свойство с вызываемым свойством public_price , к которому я применяю функции в наборе get, но оно выдает мне System.StackOverflowException ошибку при сравнении detailcombo , отличается ли объект от null, почему это происходит и как я могу это исправить?

это продукт моего класса:

  public class Producto
    {
        [Key]
        public Guid ProductoId { get; set; }
        public Guid InquilinoId { get; set; }
        private string Nombre { get; set; }

        public virtual List<DetalleCombo> DetalleCombo { get; set; } 

        private decimal _PrecioPublico;
        public decimal Precio_Publico
        {
            get
            {               
                decimal total = 0;
                if (DetalleCombo != null)
                {
                    foreach (var item in DetalleCombo)
                    {
                        total  = item.Precio * item.Cantidad;
                    }

                    return total;
                }
                else if (DetalleGenerico != null)
                {
                    if (Usar_PrecioGenerico == true)
                    {
                        return _PrecioPublico;
                    }
                    else
                    {
                        foreach (var item in DetalleGenerico)
                        {
                            if (item.Es_Seleccionado == true)
                            {
                                return item.Producto.Precio_Publico;
                            }
                        }
                        return 0;
                    }
                }
                else
                {
                    return _PrecioPublico;
                }
            }
            set { _PrecioPublico = value; }
        }
}
 

это мой класс DetalleCombo:

  public class DetalleCombo
    {
        public Guid DetalleComboId { get; set; }
        public virtual Producto Producto { get; set; }
        public decimal Cantidad { get; set; }
        public decimal Precio { get; set; }        
    }
 

это мой класс DetalleGenerico:

 public class DetalleGenerico
    {
        public Guid DetalleGenericoId { get; set; }
        public virtual Producto Producto { get; set; }
        public bool Es_Seleccionado { get; set; }       
    }
 

ошибка:
введите описание изображения здесь

Комментарии:

1. Подсказка: установите точку останова в строке return item.Producto.Precio_Publico; и узнайте, как использовать отладчик

2. Поместите точку останова в свой установщик и получатели, когда отладчик прерывается, шаг за шагом и посмотрите, почему получатель или установщик вызывает себя. Переполнение стека означает, что функция, свойство или метод вызывают себя бесконечное количество раз.

3. Сильная рекомендация — поместите большую часть этого кода в частный метод, на который ссылается ваш раздел get . Более сильная рекомендация — поместите try catch вокруг этого раздела кода, иначе вы рискуете излишне фатальными сбоями. Старайтесь всегда перехватывать, но особенно в методах get / set

Ответ №1:

В этом блоке кода:

 foreach (var item in DetalleGenerico)
{
    if (item.Es_Seleccionado == true)
    {
        return item.Producto.Precio_Publico;
    }
}
return 0;
 

Строка кода

 return item.Producto.Precio_Publico;
 

Вызывает Precio_Publico бесконечный вызов свойства. Вы постоянно попадаете в этот foreach цикл.

Каждый раз Precio_Publico , когда вызывается таким образом, вы добавляете фрейм стека в стек, пока в стеке не закончится место, вызывая переполнение стека.

Комментарии:

1. обладает хорошим зрением (хотя поиск рекурсивного доступа к свойству является первым шагом к решению многих переполнений стека .NET). Вам нужно изменить эту строку на return item.Producto._PrecioPublico . В общем, большинство. ЧИСТЫЙ код назвал бы это резервное поле _precioPublico либо одним precioPublico , либо другим. Если вы установите четкое соглашение об именовании, в котором поля и свойства выглядят очень по-разному на первый взгляд, то это менее вероятно.

2. причиной этой ошибки было использование отложенной загрузки в blazor webassembly

3. удалите эту строку при запуске. UseLazyLoadingProxies()); в моем подключении к базе данных