在C#中使用继承类作为实例List

时间:2013-09-01 23:24:19

标签: c# .net winforms design-patterns ilist

Hello stackoverflow社区!

让我们开始吧!

我有一个小班Person

class Person
{
    public string name { get; set; }
}

它有一个后代Employee

class Employee : Person
{
    public int salary { get; set; }
}

第二个后代是Guest

class Guest: Person
{
    public int id { get; set; }
}

确定!看起来不错:)

现在,我想在一个控件ListView

中显示所有员工 OR 来宾的列表

我为列表管理PeopleList创建了一个类(这是非常必要的):

class PeopleList
{
    public List<Person> People { get; set; }

    ...

    public void LoadListFromFile()
    {
        // Load logic

        this.People = new List<?>(source);
    }
}
你知道这个问号吗?没有?再看一下代码!

如何创建List的实例,我可以使用类似这样的类:

// This instance with the list of Person objects
PeopleList list = new PeopleList();

foreach (Employee e in list.People)
{
    Debug.WriteLine(e.salary.toString());
}

// This instance with the list of Guest objects
PeopleList list = new PeopleList();

foreach (Guest g in list.People)
{
    Debug.WriteLine(g.id.toString());
}

P.S。我是c#的新手,我认为我的架构有问题。也许你指出我的模式解决了我的问题。我真的需要你的帮助!谢谢!

4 个答案:

答案 0 :(得分:4)

我认为你在OfType库{@ 1}}之后:

System.Linq

答案 1 :(得分:1)

与所有死者共享的人物中唯一的字段是字段“名称”,因此,如果您将列表中的每个项目投射到人物,则只能访问“姓名”。

您有几个选项可以解决此问题。 1)您可以将所有公共字段移动到基类中,但这可能不需要,因为它会破坏对象层次结构的点,或者2)您可以使用"Is" keyword键入check,每个人都在列表,所以看看它是什么类型的人,然后cast该人在你操作它之前到适当的死者类。

例如:

foreach (Person p in list.People)
{
    if(p is Employee)
    {
      Debug.WriteLine(((Employee)p).salary.toString());
    }

    if(p is Guest)
    {
      Debug.WriteLine(((Guest)p).Id.toString());
    }
}

这是另一种更清晰的投射方式

foreach (Person p in list.People)
{
    if(p is Employee)
    {
      Employee employee = p as Employee;

      Debug.WriteLine(employee.salary.toString());
    }

    if(p is Guest)
    {
      Guest guest = p as Guest;     

      Debug.WriteLine(guest.Id.toString());
    }

}

此外,您可以使用“是”关键字here了解有关类型检查的详情。

另外,为了清楚起见,因为它可能并不明显,其他一些人建议您在linq中使用OfType,但这更像是从混合对象列表中过滤出类似对象,而不是实际键入检查每个对象。

享受!

答案 2 :(得分:0)

正如评论所说,您可以执行以下操作;

public void LoadListFromFile()
{
    // Load logic

    this.People = new List<Person>(source);
}

然后,在适当的时候施放;

foreach (Person e in list.People.Where(p => p.GetType() == typeof(Employee)))
{
    Debug.WriteLine(((Employee)e).salary.toString());
}

答案 3 :(得分:0)

我认为在你的特定例子中,继承结构并没有增加太多的好处,但我离题了。

在您的示例中,最简单的解决方案是覆盖每个类中的ToString方法。

在运行某种计算或显示之前必须事先了解对象的确切类型,将计算的负担放在调用代码上,如果你创建第3种类型,则必须更新所有可能的引用,给你一个维护噩梦。

感觉如何表达自己的逻辑应该是对象本身的责任(在你的例子中)。

这就是覆盖ToString给你的东西,然后代表自己的责任被赋予最了解的东西(你要问的对象)。