使一个父 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()
创建查找。
我还为每一行添加了错误处理,以便您在以后遇到问题时能够看到是哪一行导致了错误。
如果您在理解更改方面有任何问题,请告诉我。
希望这不会太复杂,我只是想知道为什么这个 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()
创建查找。
我还为每一行添加了错误处理,以便您在以后遇到问题时能够看到是哪一行导致了错误。
如果您在理解更改方面有任何问题,请告诉我。