#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()); в моем подключении к базе данных