【问题标题】:Switch statement that makes different child classes of one parent class does not work使一个父类的不同子类的switch语句不起作用
【发布时间】:2015-03-19 02:40:32
【问题描述】:

希望这不是太复杂,我只是想知道为什么这个 switch 语句不起作用。 Band 是父类,子类是不同类型的乐队(RockBand、JazzCombo、SoloAct,默认)。当我使用 switch 语句时,它会捕获并产生错误,只加载 2 个波段。语法有什么问题吗?

class Bands
{
    private List<Band> bands = new List<Band>();
    private Dictionary<string, Band> bandsByName = new Dictionary<string, Band>();

    public Bands()
    {
        string fileName = @"C:\Users\Lkvideorang\Documents\Visual Studio 2013\Projects\KernRadio\KernRadio\bin\Debug\bands.txt";

        try
        {
            using (StreamReader myRdr = new StreamReader(fileName))
            {
                string line;
                while ((line = myRdr.ReadLine()) != null)
                {
                    string[] lineAra = line.Split('|');

                    switch (lineAra[1])
                    {
                        case "RockBand":
                            Band newBand = new RockBand(lineAra);
                            bands.Add(newBand);
                            bandsByName.Add(newBand.Name, newBand);
                            break;
                        case "JazzCombo":
                            Band newt = new JazzCombo(lineAra);
                            bands.Add(newt);
                            bandsByName.Add(newt.Name, newt);
                            break;
                        case "SoloAct":
                            Band newB = new SoloAct(lineAra);
                            bands.Add(newB);
                            bandsByName.Add(newB.Name, newB);
                            break;
                        default:
                            Band ddd = new Band(lineAra);
                            bands.Add(ddd);
                            bandsByName.Add(ddd.Name, ddd);
                            break;
                    }
                }
            }
            Console.WriteLine("loaded " + bands.Count + " bands");
        }
        catch
        {
            Console.WriteLine("Error reading file! Read " + bands.Count + " tunes.");
        }

    }

摇滚乐队课。这就是我的主要麻烦所在,我的教授希望我们让乐队班的成员成为音乐家,但我真的不明白如何利用它并分配给那个班。我也会发布该课程。

class RockBand : Band
    {


       private Musician vocalist;
       private Musician bass;
       private Musician drums;
       private Musician guitar;


        public RockBand (string[] lineAra) : base (lineAra,)
        {
            vocalist.Name = lineAra[2];




        }
    }

类音乐家

class Musician
{
    string name;
    string instrument;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public string Instrument
    {
        get { return instrument; }
        set { instrument = value; }
    }

   public Musician(string [] lineAra)
    {
        name = lineAra[0];
        instrument = lineAra[1];
    }
}

txt文件长这样

Al & GenJam|JazzCombo|GenJam|GenJam|GenJam|GenJam|Al Biles 约翰·科尔特兰四重奏|爵士组合|麦考伊·泰纳|吉米·加里森|埃尔文·琼斯|约翰·科尔特兰 披头士|摇滚乐队|约翰列侬|保罗麦卡特尼|林戈斯塔尔|乔治哈里森 迈尔斯戴维斯五重奏|爵士组合|赫比汉考克|罗恩卡特|托尼威廉姆斯|迈尔斯戴维斯|韦恩肖特 迈克尔杰克逊|独奏 奇怪的铝|SoloAct 波尔卡朋克|波尔卡乐队 赫比汉考克三重奏|爵士组合|赫比汉考克|罗恩卡特|托尼威廉姆斯

花花公子.txt

John Lennon|guitar
Paul McCartney|bass
Ringo Starr|drums
George Harrison|guitar
Al Biles|trumpet
GenJam|code
Michael Jackson|vocals
Weird Al|accordian
John Coltrane|sax
Miles Davis|trumpet
Wayne Shorter|sax
McCoy Tyner|piano
Jimmy Garrison|bass
Elvin Jones|drums
Tony Williams|drums
Herbie Hancock|piano
Ron Carter|bass

另外,如果有一种方法可以让 newBand 在每种情况下重复而不是我为每种情况使用不同的变量,那将是惊人的。提前致谢!!

【问题讨论】:

  • @GrantWinney 感谢您的帮助!这是我得到错误读取文件的错误!读2首曲子。 System.NullReferenceException:对象引用未设置为对象的实例。在 C:\Users\Lkvideorang\Documen ts\Visual Studio 2013\Projects\KernRadio\KernRadio\RockBand.cs:KernRadio.Bands..ctor() 中的 KernRadio.RockBand..ctor(String[] lineAra) 中的第 21 行c:\Users\Lkvideorang\Documents\Visual Studio 20 13\Projects\KernRadio\KernRadio\Bands.cs:line 35
  • @LucasKern RockBand 的构造函数有错误。我猜有一个操作会产生错误。让我们知道 RockBand 代码
  • @LucasKern 发布Band 类代码 - 这可能是错误的来源。我猜你正在尝试索引一个不存在的元素,即奇怪的 Al 条目的 lineAra[2]。
  • @Fendy 好的,我已经编辑了我的帖子。感谢您的帮助!
  • @RagtimeWilly 我已经编辑了帖子,谢谢!

标签: c# database switch-statement streamreader


【解决方案1】:

您获得NullReferenceException 的原因是您试图在初始化音乐家对象之前设置音乐家的名称。你想做的是这样的:

public class RockBand : Band
{
    private Musician vocalist;
    private Musician bass;
    private Musician drums;
    private Musician guitar;

    public RockBand (string[] lineAra) 
        : base(lineAra)
    {
        if (lineAra.Length >= 3)
            vocalist = new Musician(lineAra[2], "Vocals");

        if (lineAra.Length >= 4)
            bass = new Musician(lineAra[3], "bass");

        if (lineAra.Length >= 5)
            drums = new Musician(lineAra[4], "Drums");

        if (lineAra.Length >= 6)
            guitar = new Musician(lineAra[5], "Guitar");
    }
} 

为此,您必须向Musician 添加另一个构造函数:

public Musician(string name, string instrument)
{
    this.Name = name;
    this.Instrument = instrument;
}

请注意,在尝试访问该元素之前,我还添加了一个检查以查看该元素是否存在于数组中。这是为了避免IndexOutOfRangeException

您还可以简化加载文件的代码:

public Bands()
{
    string fileName = @"C:\Users\Lkvideorang\Documents\Visual Studio 2013\Projects\KernRadio\KernRadio\bin\Debug\bands.txt";

    string[] allLines;

    try
    {
        allLines = File.ReadAllLines(fileName);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error reading file! Exception: " + ex.Message);
        return;
    }

    bands = new List<Band>();

    foreach (var line in allLines)
    {
        try
        {
            string[] lineAra = line.Split('|');

            if (lineAra.Length < 2) continue;

            switch (lineAra[1])
            {
                case "RockBand":
                    bands.Add(new RockBand(lineAra));
                    break;
                case "JazzCombo":
                    bands.Add(new JazzCombo(lineAra));
                    break;
                case "SoloAct":
                    bands.Add(new SoloAct(lineAra));
                    break;
                default:
                    bands.Add(new Band(lineAra));
                    break;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error parsing line {0}. Exception: {1}", line, ex.Message);
        }
    }

    bandsByName = bands.ToList().ToDictionary(x => x.Name, x => x);

    Console.WriteLine("loaded " + bands.Count + " bands");
}

在这里,我将流阅读器更改为 File.ReadAllLines,并在加载所有波段后使用 .ToDictionary() 创建查找。

我还为每一行添加了错误处理,以便您在以后遇到问题时能够查看是哪一行导致了错误。

如果您在理解更改方面有任何问题,请告诉我。

【讨论】:

  • 这帮助很大,谢谢。我仍然不知道如何解决我的整体问题。我可以用我在 RockBand 中创建的音乐家做什么?还有另一个类 Dudes 的功能与 Bands 非常相似,它读取 dudes.txt 并制作一堆音乐家对象。那么在 RockBand 中创建的那些不是已经存在了吗?我不知道....
  • @LucasKern 我认为这似乎是您在这里提出的问题:stackoverflow.com/questions/29134109/… 如果您想接受这个答案,我会尝试在其他问题中为您澄清。
  • 是的,那太好了。由于我最初的措辞不佳,我已经放弃了这个问题。
【解决方案2】:

您使用的 string.Split('|') 不正确。

你首先需要获取整个字符串,然后只调用一次split。

using (StreamReader myRdr = new StreamReader(fileName))
        {
            string entireText;
            if((entireText= myRdr.ReadToEnd()) != null)
            {
                string[] entireTextArray = entireText.Split('|');
                foreach(string band in entireTextArray )
                {
                switch (band)
                {
                    case "RockBand":
                        Band newBand = new RockBand(lineAra);
                        bands.Add(newBand);
                        bandsByName.Add(newBand.Name, newBand);
                        break;
                    case "JazzCombo":
                        Band newt = new JazzCombo(lineAra);
                        bands.Add(newt);
                        bandsByName.Add(newt.Name, newt);
                        break;
                    case "SoloAct":
                        Band newB = new SoloAct(lineAra);
                        bands.Add(newB);
                        bandsByName.Add(newB.Name, newB);
                        break;
                    default:
                        Band ddd = new Band(lineAra);
                        bands.Add(ddd);
                        bandsByName.Add(ddd.Name, ddd);
                        break;
                }
                }
            }
        }

【讨论】:

  • 这是我使用它时遇到的错误。谢谢你的帮忙!读取文件错误!读2首曲子。 System.ArgumentException:已添加具有相同键的项目。在 System.ThrowHelper.ThrowArgumentException(ExceptionResource 资源) at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boo lean add) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value) at KernRadio.Bands..ctor() in c:\Users\Lkvideorang\Documents\ Visual Studio 20 13\Projects\KernRadio\KernRadio\Bands.cs:第 39 行
  • 字典不允许重复键。
  • 你知道副本在哪里吗??
  • 您似乎在第一行添加了多个 GenJam。 Al & GenJam|JazzCombo|GenJam|GenJam|GenJam|GenJam|Al Biles
  • 哦,那是必要数据的一部分,GenJam 是我老师制作的程序,它会演奏多种乐器。我真的只需要读取 array[1] 因为它决定了它是什么类型。我就是不能让它工作
猜你喜欢
  • 2018-09-30
  • 1970-01-01
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
  • 2019-04-12
相关资源
最近更新 更多