2013-08-17 2 views
0

WHYYYYYYY?StackOverflowException без видимых причин .. Это действительно раздражает

Ниже приведено примерно половина моего кода, так как я удалил большую часть его, а также все волосы, которые я потерял, пытаясь решить эту проблему. Независимо от того, что я удаляю или изменяю, я продолжаю получать исключение StackOverflowException.

Это очень странно, потому что этот точный код работал раньше.

Пожалуйста, дайте мне совет на все, потому что я невежественный ...

Я проверил это, и я не думаю, что это то, что происходит:

  • Infinite рекурсивный цикл
  • программа просто бежит из стека

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Net; 

namespace ConsoleApplication10 
{ 
class Program 
{ 
    public int currentDialogueID = 0; 

    List<NPC> NPCList = new List<NPC>() { 
      new NPC(0, "Man", 1, true), 
      new NPC(1, "Woman", 1, true), 
      new NPC(2, "Troll", 3, true) 
     }; 

    static void Main(string[] args) 
    { 
     Program d = new Program(); 
     d.Init(); 
     Console.ReadKey(false); 
    } 

    void Init() 
    { 
     getNPCByName("Man").NPCDialogue(); 
    } 

    public NPC getNPCByName(string npcName) 
    { 
     IEnumerable<NPC> myNPCsName = from nn in NPCList 
             where nn._name.ToLower() == npcName.ToLower() 
             orderby nn._name ascending 
             select nn; 

     foreach(NPC nn2 in myNPCsName) 
     { 
      return nn2; 
     } 

     return null; 
    } 

    public NPC getNPCByID(int npcID) 
    { 
     IEnumerable<NPC> NPCsByID = from ni in NPCList 
            where ni._npcID == npcID 
            orderby ni._npcID ascending 
            select ni; 

     foreach(NPC ni2 in NPCsByID) 
     { 
      return ni2; 
     } 

     return null; 
    } 

    public string getNPCNameByID(int npcid) 
    { 
     return getNPCByID(npcid)._name; 
    } 
} 

class NPC : Program 
{ 
    public string _name = "null"; 
    public int _level; 
    public int _npcID; 
    public int _maxDamage; 
    public bool _canFight = false; 

    public NPC(int npcID = 0, string name = "null", int level = 0, bool canSpeak = false, bool canFight = false, int maxDamage = 0) 
    { 
     _level = level; 
     _name = name; 
     _npcID = npcID; 
     _canFight = canFight; 
     _maxDamage = maxDamage; 
    } 

    public void NPCDialogue() 
    { 
     currentDialogueID = _npcID; 
     switch(_npcID) 
     { 
      case 0: 
      NPCSpeak("Man test... ... ..."); 
      break; 

      case 1: 
      NPCSpeak("Woman test"); 
      break; 

      case 2: 
      NPCSpeak("I'm Elad the Troll, Ramzes your ear is that of an elf"); 
      break; 

      default: 
      return; 
     } 
    } 

    public void NPCSpeak(string text, int npcID = 99999) 
    { 
     if(npcID == 99999) 
      npcID = currentDialogueID; 
     if(npcID != 99999) 
      type(getNPCNameByID(npcID) + ": " + text); 
    } 

    public void type(string x) 
    { 
     Random rnd = new Random(); 
     char[] xx = x.ToCharArray(); 
     for(int i = 0; i < xx.Length; i++) 
     { 
      Console.Write(xx[i]); 
      System.Threading.Thread.Sleep(rnd.Next(10, 120)); 
      if(xx[i] == ':' || (xx[i] == '.' && xx[i - 1] != '.' && xx[i + 1] != '.') || xx[i] == '!' || xx[i] == '\n' || xx[i] == '?') 
      { 
       System.Threading.Thread.Sleep(rnd.Next(400, 1500)); 
      } 
     } 
    } 
} 

class Item : Program 
{ 
    public string _name = "null"; 
    public string _description = "How did you get this?"; 
    public bool _isWeapon = false; 
    public int _maxDamage; 
    public int _itemID = 0; 

    public Item(int itemID = 0, string name = "null", string description = "null", bool isWeapon = false, int maxDamage = 0) 
    { 
     _itemID = itemID; 
     _name = name; 
     _description = description; 
     _isWeapon = isWeapon; 
     _maxDamage = maxDamage; 
    } 
} 
} 

ответ

1

Похоже, вы немного смущены тем, какие классы следует унаследовать где.

Ваш класс программы создает новый список из 3 NPC. NPC наследует от Программы, что означает (в основном), что весь код из программы удаляется в NPC. Это означает, что поскольку Программа создает список из 3 NPC при его создании, NPC наследует этот код и создает дополнительный список из 3 дополнительных NPC, каждый из которых наследует от программы и создает еще 3 NPC и т. Д. До тех пор, пока стек переполняется.

Советуем посмотреть на стек вызовов, чтобы поймать этот материал, является хорошим советом. Я бы также добавил, что наследование обычно используется несколько иначе. Просто потому, что NPC и Item используются вашей Программой, это не значит, что они должны (или должны) наследовать ее. Наследование лучше всего использовать между классами, где один является подмножеством другого, но имеет более конкретные характеристики. Общий пример состоит в том, что класс Animal со свойствами «Family, Species, Age» и т. Д. Может быть унаследован классом Dog, который также обладает всеми этими свойствами, но вы также можете использовать свойство Dog, специфическое для Dog, и «Breed».

В вашем случае NPC может быть родительским классом, который наследуется «Merchant» или «Companion», оба из которых по-прежнему являются NPC (и поэтому должны иметь все основные характеристики NPC), но могут также иметь различное поведение, характерное для их подкласса. Предмет может быть унаследован «Оружием» и «Щитом», которые являются обеими пунктами, но имеют разные дополнительные характеристики для отслеживания.

+0

Ничего себе, очень подробное объяснение, большое вам спасибо! Я просто хотел, чтобы они наследовали, потому что я хотел использовать все переменные и функции в классах ... Но я просто сделал отдельный класс, содержащий все переменные, которые мне нужны, и сделал статический экземпляр этого для доступа к нему повсюду. Я даже не знаю, лучший ли это, но хорошо ... – Adam

+0

Я не очень много знаю о том, как обычно программируются игры, но это звучит не так, как будто это особенно плохая практика, чтобы иметь какие-то Класс GameState, который содержит важные игровые переменные, к которым должны обращаться другие классы, в зависимости от того, что вы там храните. Хорошая объектно-ориентированная практика хранения релевантных данных в классе, в котором он больше всего связан, поэтому, если у вас есть коллекция «Inventory», вы, вероятно, захотите сохранить ее в классе NPC или Player, а не в классе GameState. – UpQuark

-2
Program d = new Program(); 

Вы должны удалить эту строку, вы вызываете программу конструктор каждый раз, когда вы запускаете конструктор программы, в результате чего StackOverflow

+1

Нет, это не так. Выглядишь лучше. Главная статична – xanatos

+0

Нет, это было с самого начала. Он вызывается только один раз с помощью функции Main, после этого больше нет. И мне это нужно, потому что Main является статическим. – Adam

+0

не запускает новую программу() автоматически при запуске приложения в любом случае, похоже, что вы создаете программу внутри программы здесь, которая в конечном итоге может быть рекурсивной, например, @ Xikinho90 указала – Robert

5

У вас есть NPC, что это программа, но каждая программа имеет список 3 NPC ... Ты видишь?

В следующий раз, вы посмотрите на окно Call Stack и вы увидите

ConsoleApplication5.exe!ConsoleApplication10.Program.Program() Line 13 + 0xffffffe6 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.NPC.NPC(int npcID, string name, int level, bool canSpeak, bool canFight, int maxDamage) Line 77 + 0x8 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.Program.Program() Line 15 + 0x40 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.NPC.NPC(int npcID, string name, int level, bool canSpeak, bool canFight, int maxDamage) Line 77 + 0x8 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.Program.Program() Line 15 + 0x40 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.NPC.NPC(int npcID, string name, int level, bool canSpeak, bool canFight, int maxDamage) Line 77 + 0x8 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.Program.Program() Line 15 + 0x40 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.NPC.NPC(int npcID, string name, int level, bool canSpeak, bool canFight, int maxDamage) Line 77 + 0x8 bytes C# 
ConsoleApplication5.exe!ConsoleApplication10.Program.Program() Line 15 + 0x40 bytes C# 

, то вы можете нажать на линии и посмотреть, где был начат следующий этап.

+0

Вся программа запускается снова, когда я запускаю класс NPC? ... – Adam

+0

Нет, весь класс создается снова. Класс не является программой, даже если вы называете ее программой. – xanatos

+0

Хорошо тогда .. Не знал, что .. Ну, большое спасибо! – Adam

Смежные вопросы