使一个父 class 的不同子 classes 的 Switch 语句不起作用

Switch statement that makes different child classes of one parent class does not work

希望这不会太复杂,我只是想知道为什么这个 switch 语句不起作用。乐队是父乐队 class,子乐队 class 是不同类型的乐队(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。这是我的主要问题所在,我的教授希望我们让乐队的成员 class 成为音乐家,但我真的不明白如何利用它并分配那个 class。生病 post 那 class 也是。

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 音乐家

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
John Coltrane 四重奏|JazzCombo|McCoy Tyner|Jimmy Garrison|Elvin Jones|John Coltrane
披头士|摇滚乐队|约翰·列侬|保罗·麦卡特尼|林戈·斯塔尔|乔治·哈里森
迈尔斯·戴维斯五重奏|JazzCombo|赫比·汉考克|罗恩·卡特|托尼·威廉姆斯|迈尔斯·戴维斯|韦恩·肖特
迈克尔·杰克逊|SoloAct
奇怪的艾尔|SoloAct
波尔卡朋克|波尔卡乐队
赫比汉考克三重奏|JazzCombo|赫比汉考克|罗恩卡特|托尼威廉姆斯

dudes.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 在每种情况下重复,而不是我为每种情况使用不同的变量,那将是惊人的。提前致谢!!

您使用的 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;
                }
                }
            }
        }

你得到 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");
}

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

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

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