我有一个情况,我想创建一个可以保存父类型和子类型的字典。我想存储不同的子类型并能够调用他们的数据。
我遇到的问题是,当从字典中提取对象时,它们被视为其父类型,因为字典类型设置为父对象。我想出访问其附加属性的唯一方法是使用 var 实例化一个新对象(见下文)。
任何帮助将不胜感激。另外,如果我的术语/术语不正确,请随时纠正我,因为我正在尝试学习。谢谢!
更新:我稍微更新了我的代码,试图准确地传达我正在尝试做的事情。 (添加了foreach循环)。
public class parent
{
public string name;
}
public class child : parent
{
public int age;
}
public class library
{
}
public class Program
{
public static void Main(string[] args)
{
Dictionary<int, parent> dictionary = new Dictionary<int, parent>();
child child1 = new child();
child child2 = new child();
child1.age = 5;
child2.age = 10;
dictionary.Add(1,child1);
dictionary.Add(2,child2);
foreach(KeyValuePair<int, parent> d in dictionary)
{
Console.WriteLine(d.age);
}
}
}
这是仅访问字典child
成员的另一种方法:
Dictionary<int, parent> dictionary = new Dictionary<int, parent>();
child child1 = new child();
child child2 = new child();
child1.age = 5;
child2.age = 10;
dictionary.Add(1,child1);
dictionary.Add(2,child2);
dictionary.Add(45, new parent());
foreach(var c in dictionary.Select(x => x.Value).OfType<child>())
{
Console.WriteLine(c.age);
}
这让我只5
10
,忽略了我放入字典中的parent
对象。
如果你这样做,你的设计可能是错误的,但你已经有了正确的设计。
var child1a = child1 as child;
不实例化新对象。它只是下降到child
类型。向下转换是一种代码气味,因此请考虑将设计重新加工到不需要的地方。
此外,如果强制转换失败,as
将返回null
,因此您应该检查它:
var child1a = child1 as child;
if (child1a != null)
Console.WriteLine(child1a.age);
最后,您从未在代码中实际使用字典,您可能希望这样做:
var child1a = dictionary[1] as child;
if (child1a != null)
Console.WriteLine(child1a.age);
对于您的更新,该循环将永远不起作用(也不应该)。并非集合中的所有对象都保证具有"age"属性。
关于你的循环,你可以这样做:
foreach (child item in dictionary.Values)
{
...
}
或:
foreach (KeyValuePair<int, parent> kvp in dictionary)
{
if (kvp.Value is child)
{
child item = (child)kvp.Value;
...
}
}
这将从您的值集合中提取child
项,并让您这样使用它们。如果这就是你所做的一切,那么Dictionary
在这里是矫枉过正。