0

为什么YYYYYY?

以下是我的代码的大约一半,因为我已经删除了大部分代码以及我在尝试解决这个问题时失去的每一根头发。无论我删除或更改什么,我都会不断收到 StackOverflowException。

这非常奇怪,因为这个完全相同的代码更早地工作了。

请给我任何建议,因为我一无所知...

我已经检查过了,但我认为这不是发生的事情:

  • 无限递归循环
  • 程序只是用完了堆栈空间

­

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

3 回答 3

5

你有一个程序的 NPC,但每个程序都有一个包含 3 个 NPC 的列表……你明白吗?

下一次,您查看调用堆栈窗口,您会看到

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#

然后您可以单击这些行并查看下一步的启动位置。

于 2013-08-17T12:55:06.380 回答
1

看起来你对应该在哪里继承哪些类有点困惑。

您的程序类创建了一个包含 3 个 NPC 的新列表。NPC 继承自 Program,这意味着(基本上)程序中的所有代码都被放入 NPC。这意味着,由于 Program 在实例化时创建了一个包含 3 个 NPC 的列表,因此 NPC 继承了此代码并创建了另外一个包含 3 个 NPC 的列表,每个 NPC 都继承自 program 并分别创建 3 个 NPC,依此类推,直到堆栈溢出。

查看调用堆栈以捕获这些内容的提示是个好建议。我还要补充一点,继承的使用通常略有不同。仅仅因为 NPC 和 Item 被您的程序使用并不意味着他们必须(或应该)继承它。继承最好在类之间使用,其中一个是另一个的子集,但具有更具体的特征。一个普遍的例子是,具有“家庭、物种、年龄”等属性的类 Animal 可能会被同样具有所有这些属性的 Dog 类继承,但您可能还想使用 Dog 特定属性“Breed”。

在您的情况下,NPC 可能是由“Merchant”或“Companion”继承的父类,它们仍然是 NPC(因此应该具有所有基本的 NPC 特征),但也可能具有特定于其子类的不同行为。物品可能由“武器”和“盾牌”继承,它们都是物品,但有不同的附加特性需要跟踪。

于 2013-08-17T13:14:48.797 回答
-2
Program d = new Program();

您必须删除此行,每次运行程序构造函数时都在调用程序构造函数,导致stackoverflow

于 2013-08-17T12:53:05.683 回答