Reputation: 25
I have 3 classes: "ChemDataChemicals(Super)", "ChemDataAlcohol(Sub), "ChemDataAcidBase"(Sub) and a common List( type: ChemDataChemicals) which holds all the objects. My superClass holds most of my fields but the subclasses are both containing one extra field each - pH(decimal) and VolPercentage(decimal).
The code below should add the item.Name and item.VolPercentage/item.pH in a ListBox, but I can't get access to my field in my subclass.
foreach (ChemDataChemicals item in tmpChemDataChemicalsList)
{
if (item is ChemDataAlcohol)
{
listBox1.Items.Add(String.Format("{0}: {1}%", item.Name, (ChemDataAlcohol)item.VolPercentage));
}
else if (item is ChemDataAcidBase)
{
listBox1.Items.Add(String.Format("{0}: {1}M", item.Name, item.pH));
}
}
I've tried some casting, but nothing seems to work. (Windows Forms - C#) Thanks,
Upvotes: 2
Views: 460
Reputation: 1562
There's another way to access items of just one subclass from the list, if you have a more general problem, and that's to use the OfType<T> extension method on any collection.
private class Chemical
{
public string formula;
}
private class ChemDataAlcohol : Chemical
{
public string Name;
}
private class ChemDataAcidBase : Chemical
{
public decimal pH; // at 1.0 M
}
public static void Test()
{
Chemical[] chemicals = {
new Chemical { formula = "H2O" },
new ChemDataAcidBase { formula = "H2SO4", pH = 0 },
new ChemDataAlcohol { formula = "C2H6O", Name="ethanol" },
new Chemical { formula = "CO2" },
new ChemDataAcidBase { formula = "CH3COOH", pH = 2.4M },
};
List<ChemDataAlcohol> alcohols = chemicals.OfType<ChemDataAlcohol>().ToList();
foreach (ChemDataAlcohol alcohol in alcohols) { string name = alcohol.Name; }
List<ChemDataAcidBase> acids = chemicals.OfType<ChemDataAcidBase>().ToList();
foreach (ChemDataAcidBase acid in acids) { decimal pH = acid.pH; }
}
Downsides: it isn't appropriate in every circumstance, and would take a certain amount of adapting to fit the need in your question.
Upvotes: 0
Reputation: 26635
Change
(ChemDataAlcohol)item.VolPercentage
to
((ChemDataAlcohol)item).VolPercentage
Also, I suggest you to use as
keyword:
(item as ChemDataAlcohol).VolPercentage
Because, with the first method, if the cast fails, an exception is thrown. With the as
method, it results in null, which can be checked for, and avoid an exception being thrown.
Upvotes: 2