【问题标题】:System.StackOverflowException while filling the list填充列表时出现 System.StackOverflowException
【发布时间】:2017-09-29 11:51:47
【问题描述】:

我会先粘贴代码,这样你就可以看到我在说什么:

namespace Radni_sati
{
public class Blagdani
{
    public List<Blagdani> Blagdani_lista = new List<Blagdani>();
    public DateTime datum { get; set; }
    public string dan_u_tjednu { get; set; }

    public Blagdani()
    {
        Blagdani KlasaBlagdan6 = new Blagdani();
        KlasaBlagdan6.datum = new DateTime(2017, 08, 05);
        KlasaBlagdan6.dan_u_tjednu = "Subota";
        Blagdani_lista.Add(KlasaBlagdan6);

        Blagdani KlasaBlagdan7 = new Blagdani();
        KlasaBlagdan7.datum = new DateTime(2017, 08, 15);
        KlasaBlagdan7.dan_u_tjednu = "Utorak";
        Blagdani_lista.Add(KlasaBlagdan7);

        //test blagdan
        Blagdani KlasaBlagdan8 = new Blagdani();
        KlasaBlagdan8.datum = new DateTime(2017, 09, 29);
        KlasaBlagdan8.dan_u_tjednu = "Petak";
        Blagdani_lista.Add(KlasaBlagdan8);

    } 
//some code afterwards

所以我的意思是填写该列表,以便我以后可以使用它,我不太确定我是否从我在互联网上阅读的内容中了解我的情况。会提供一些解释。

附:如果有人可以给我一个示例,如何使用这两个属性(datum,dan_u_tjednu)在同一类中填写该列表,那就太好了。

【问题讨论】:

  • 构造函数中的代码不属于那里。
  • 您的构造函数正在调用自己。递归。
  • 每次你使用new Blagdani();时,所有这些代码都被称为AGAIN
  • 为什么Holiday 实例包含List&lt;Holiday&gt;?也许该列表应该是static,您可以在静态构造函数中创建它。
  • 哦,对不起,我以为你是在你的本土文化下跑步的。在这种情况下,您必须执行以下操作:CultureInfo.GetCultureInfo("hr-HR").DateTimeFormat.GetDayName(datum.DayOfWeek)

标签: c# list class


【解决方案1】:

试试这个,你递归调用你的构造函数,每次你初始化对象时,它都会进入无限循环,所以你得到溢出异常。通过重写构造函数(或者您可以使用方法)并将 List 转换为静态,您不会递归地调用构造函数,每个构造函数都会做自己的工作,定义变量因为静态将保留您的 Blagdani,如果它不是静态的,则每个 Blagdani 属性将是最后一个值。

public static List<Blagdani> Blagdani_lista = new List<Blagdani>();
public DateTime datum { get; set; }
public string dan_u_tjednu { get; set; }

public Blagdani() {
       DateTime date = new DateTime(2017, 08, 05);
       string something = "Subota";
       Blagdani b = new Blagdani(date, something);


       date = new DateTime(2017, 08, 15);
       something = "Utorak";
       b = new Blagdani(date, something);

       date = new DateTime(2017, 08, 29);
       something = "Petak";
       Blagdani qwe = new Blagdani(date, something);

}
public Blagdani(DateTime dt, string something) { // override constructor
       this.datum = dt;
       this.dan_u_tjednu = something;
       Blagdani_lista.Add(this);
}

希望有帮助,

【讨论】:

  • 三个假期的默认初始化属于静态构造函数,因为它现在是一个静态列表(这很有意义)。除此之外,你应该解释你做了什么以及为什么它会解决这个问题。话虽如此,您也应该解释一下这个问题。
  • 我在写 :) @TimSchmelter
  • @Berkay 喜欢你的解释,我还有一个问题要问你:你告诉我,如果我不将该列表设置为静态,它只会创建一个条目,而该条目将是最后一个我设置(最后一个假期,因为这就是 blagdan 的意思;))
  • 不是最后一个条目,您将有 3 个计数,但它们的所有属性都是相同的。例如,它们都具有相同的日期和相同的 dan_u_tjednu(“Petak”)。 @MarkoPetričević
  • @Berkay 是的 3 个计数,没错,但它总是 3 个相同的。但是静态如何防止这种情况发生在这里?有什么收获?
【解决方案2】:

为什么不在另一个班级管理列表? 从 Blagdani 类中删除列表并像这样修改构造函数:

public Blagdani(string Xdan_u_tjednu_, DateTime Xdatum)
{
    dan_u_tjednu = Xdan_u_tjednu_;
    datum = Xdatum;
}

然后创建一个新类,如:

public class ListManager
{
    public List<Blagdani> Blagdani_lista = new List<Blagdani>();

}

现在您可以通过以下方式添加到此列表中:

Blagdani_lista.Add(new Blagdani("Subota",new DateTime(2017, 08, 05));
Blagdani_lista.Add(new Blagdani("Utorak",new DateTime(2017, 08, 15));

【讨论】:

  • 你的解决方案有效,唯一我不喜欢的就是创建一个新类,因为这是我在提问时想要避免的。无论如何谢谢=)
  • 您不必创建 ListManager 类。您可以将列表保留在 Main 类中。这也有效。没有上下文很难说。但我想你可以找到最适合你的解决方案。
【解决方案3】:

你所要做的就是让你的List和构造函数static。这样在构造函数中就没有递归调用,因为static 指的是类型本身,而不是类型的实例:

public class Blagdani
{
    public static List<Blagdani> Blagdani_lista;
    public DateTime datum { get; set; }
    public string dan_u_tjednu { get; set; }

    static Blagdani()
    {
        Blagdani_lista = new List<Blagdani>
        {
            new Blagdani {datum = new DateTime(2017, 08, 05), dan_u_tjednu = "Subota"},
            new Blagdani {datum = new DateTime(2017, 08, 15), dan_u_tjednu = "Utorak"},
            new Blagdani {datum = new DateTime(2017, 09, 29), dan_u_tjednu = "Petak"}
        };
    }
}

现在可以在不创建类型实例的情况下访问列表,例如:

static void Main()
{
    foreach(var blagdani in Blagdani.Blagdani_lista)
    {
        Console.WriteLine($"{blagdani.datum} ({blagdani.dan_u_tjednu})");
    }

    Console.Write("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

输出

【讨论】:

  • 从 2 个帖子中得到解释,这就是为什么我喜欢 stackoverflow 及其社区,这又是 =)
  • 不客气!请注意,这在某些方面与接受的答案不同。有了这个答案,您可以立即使用该列表,而无需创建任何实例,使用:Blagdani.Blagdani_lista。有了接受的答案,如果您在没有先创建实例的情况下访问列表,则列表为空。如果您创建一个实例,则该列表是正确的。但是,如果您碰巧创建了 another 实例,则列表将是两倍大小,并带有重复项。这就是为什么我推荐 static 构造函数而不是专门的实例构造函数的原因。
【解决方案4】:

这个构造函数是递归的。由于它每次调用时都会创建同一个类的新实例,因此本质上是一个无限循环,只有在运行时耗尽内存或堆栈空间来支持它时才会终止。

【讨论】:

    【解决方案5】:
    Let me Explain what is happening in your case:
    Below is your code:
    1. Please focus on the comments section i.e which are in the form (// something ) 
       or is in the italic font
    

    命名空间 Radni_sati { 公共课布拉格达尼 { 公共列表 Blagdani_lista = new List(); 公共日期时间数据 { 获取;放; } 公共字符串 dan_u_tjednu { 获取;放; }

        public Blagdani()
        {
            **Blagdani KlasaBlagdan6 = new Blagdani();**    // *recursive call to the constructor again and again*
            KlasaBlagdan6.datum = new DateTime(2017, 08, 05);
            KlasaBlagdan6.dan_u_tjednu = "Subota";
            Blagdani_lista.Add(KlasaBlagdan6);
    
            Blagdani KlasaBlagdan7 = new Blagdani();
            KlasaBlagdan7.datum = new DateTime(2017, 08, 15);
            KlasaBlagdan7.dan_u_tjednu = "Utorak";
            Blagdani_lista.Add(KlasaBlagdan7);
    
            //test blagdan
            Blagdani KlasaBlagdan8 = new Blagdani();
            KlasaBlagdan8.datum = new DateTime(2017, 09, 29);
            KlasaBlagdan8.dan_u_tjednu = "Petak";
            Blagdani_lista.Add(KlasaBlagdan8);
    
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 2014-12-27
      • 2023-03-31
      相关资源
      最近更新 更多