2014-12-11 117 views
1

我有一种情况,我想创建一个可以容纳父类和子类型的字典。我想存储不同的孩子类型,并能够调用他们的数据。从存储父类类型的字典访问子属性

我正在运行的问题是,当将对象拉出字典时,它们被视为它们的父类型,因为字典类型被设置为父对象。我想通过使用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); 

    }     


      } 
} 
+0

即使您的代码显示了所涉及的对象和类型,它实际上也不会显示您遇到的问题。展示代表您问题的最少量代码是适当的礼节。 – Enigmativity 2014-12-11 00:22:15

回答

1

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

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); 

对你的更新,该循环将从来没有工作(也不应该)。并非您集合中的所有对象都保证具有“年龄”属性。

对于你的循环,你可以做到这一点:

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方式矫枉过正在这里。

+0

你说得对。我其实已经打算把“var child1a = new child1作为孩子;”当我的意思是实例化一个新的对象。但是,我仍然在寻找一种解决方案,将对象作为子对象从字典中移出。我会更新我的代码,但我期望做的是将每个项目从字典中拉出并访问子属性。谢谢。 – tchock 2014-12-11 00:52:20

+0

@parrotsnest我会更新我的答案,包括这一点,但你根本**不能**做到这一点。如果你将它存储为基类,它将以这种方式出现,故事结束。您必须投射以获取派生属性。这是必要的事实意味着你可能会错误地设计你的设计。修复您的设计是*真实*解决方案。 – BradleyDotNET 2014-12-11 00:59:38

+0

@parrotsnest另外'VAR child1a =新child1作为child'毫无意义可言,而不会进行编译。无论如何,实例化*不是*你在这里寻找的东西,因为看起来你已经想通了。 – BradleyDotNET 2014-12-11 01:06:48

1

这里的访问只是字典的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对象我把字典中。

+0

谢谢!这也适用。 :) – tchock 2014-12-11 03:25:07