C# 从存储父类类型的字典访问子属性

C# 从存储父类类型的字典访问子属性,c#,C#,我想创建一个可以保存父类型和子类型的字典。我想存储不同的子类型,并能够调用它们的数据 我遇到的问题是,当从字典中拉出对象时,它们被视为其父类型,因为字典类型被设置为父对象。我发现访问它们的附加属性的唯一方法是使用var实例化一个新对象(见下文) 任何帮助都将不胜感激。此外,如果我的行话/术语不正确,请在我尝试学习时随时纠正我。谢谢 更新:我稍微更新了我的代码,试图准确地传达我要做的事情。(添加了foreach循环) 公共类父类 { 公共字符串名称; } 公共类子级:父级 { 公共信息; } 公共

我想创建一个可以保存父类型和子类型的字典。我想存储不同的子类型,并能够调用它们的数据

我遇到的问题是,当从字典中拉出对象时,它们被视为其父类型,因为字典类型被设置为父对象。我发现访问它们的附加属性的唯一方法是使用var实例化一个新对象(见下文)

任何帮助都将不胜感激。此外,如果我的行话/术语不正确,请在我尝试学习时随时纠正我。谢谢

更新:我稍微更新了我的代码,试图准确地传达我要做的事情。(添加了foreach循环)

公共类父类
{
公共字符串名称;
}
公共类子级:父级
{
公共信息;
}
公共班级图书馆
{               
}
公共课程
{
公共静态void Main(字符串[]args)
{                
字典=新字典();
child child1=新的child();
child child2=新的child();
儿童1.5岁;
儿童2.年龄=10岁;
增加(1,儿童1);
添加(2,child2);
foreach(字典中的键值对d)
{
控制台写入线(d.age);
}                  
}
}

如果您这样做,您的设计可能是错误的,但您已经拥有了正确的设计

var child1a = child1 as 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(字典中的KeyValuePair kvp)
{ 
if(kvp.Value为子级)
{
子项=(子项)kvp.Value;
...
}
}

这将从您的值集合中拉出
子项
项,并允许您这样使用它们。如果这就是你所要做的,那么在这里使用
字典就太过分了。

这里有另一种方法,只访问字典的
子成员:

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);
}
Dictionary Dictionary=newdictionary();
child child1=新的child();
child child2=新的child();
儿童1.5岁;
儿童2.年龄=10岁;
增加(1,儿童1);
添加(2,child2);
Add(45,newparent());
foreach(dictionary.Select(x=>x.Value).OfType()中的变量c)
{
控制台写入线(c.age);
}

这让我只知道
5
&
10
,忽略了我放在字典中的
父对象。

即使你的代码显示了所涉及的对象和类型,但它实际上并没有显示你遇到的问题。用最少的代码来说明你的问题是恰当的礼仪。你是对的。当我想实例化一个新对象时,我实际上是想把“var child1a=new child1”作为child。但是,我仍然在寻找一种解决方案,将对象作为子对象从字典中取出。我将更新我的代码,但我希望做的是从字典中取出每个项并访问子属性。谢谢你。@parrotsnest我会更新我的答案,包括这一点,但你不能这么做。如果您将它存储为基类,它将以这种方式出现,故事结束。您必须强制转换才能获得派生属性。事实上,这是必要的,这意味着您可能设置了错误的设计。修复您的设计才是真正的解决方案。@parrotsnest另外,
var child1a=new child1 as child
毫无意义,也不会编译。无论如何,实例化并不是您在这里想要的,因为您似乎已经明白了。太棒了。这些解决方案肯定是有帮助的。我将根据您的反馈重新评估我的设计。非常感谢!
foreach (child item in dictionary.Values)
{
    ...
}
foreach (KeyValuePair<int, parent> kvp in dictionary)
{ 
   if (kvp.Value is child)
   {
       child item = (child)kvp.Value;
       ...
   }
}
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);
}