Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中对实例列表使用继承类#_C#_.net_Winforms_Design Patterns_Ilist - Fatal编程技术网

C# 在C中对实例列表使用继承类#

C# 在C中对实例列表使用继承类#,c#,.net,winforms,design-patterns,ilist,C#,.net,Winforms,Design Patterns,Ilist,大家好,我的社区 让我们开始吧 我有一个小班的人: class Person { public string name { get; set; } } А并且它有一个后代员工: class Employee : Person { public int salary { get; set; } } 第二个后代是Guest: class Guest: Person { public int id { get; set; } } class PeopleList {

大家好,我的社区

让我们开始吧

我有一个小班的

class Person
{
    public string name { get; set; }
}
А并且它有一个后代
员工

class Employee : Person
{
    public int salary { get; set; }
}
第二个后代是
Guest

class Guest: Person
{
    public int id { get; set; }
}
class PeopleList
{
    public List<Person> People { get; set; }

    ...

    public void LoadListFromFile()
    {
        // Load logic

        this.People = new List<?>(source);
    }
}
好的!看起来不错:)

现在,我想在一个控件中显示所有员工或客人的列表
ListView

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

class Guest: Person
{
    public int id { get; set; }
}
class PeopleList
{
    public List<Person> People { get; set; }

    ...

    public void LoadListFromFile()
    {
        // Load logic

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

另外,我是c#新手,我认为我在架构方面有问题。也许你能给我指出解决我问题的模式。我真的需要你的帮助!谢谢大家!

与所有死者共享的唯一个人字段是字段“姓名”,因此,如果您将列表中的每个项目转换为个人,您将只能访问“姓名”

你有几个选择来解决这个问题。1) 您可以将所有公共字段移动到基类中,但这可能是不需要的,因为它会破坏对象层次结构的点;或者2)您可以使用键入检查,检查列表中的每个人,以便查看该人是什么类型的人,然后在对其进行操作之前将该人转到相应的已死亡类

例如:

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

此外,您还可以使用“is”关键字了解有关类型检查的更多信息

另外,为了清楚起见,因为它可能并不明显,其他一些人建议您在linq中使用类型,但这更像是一种从混合对象列表中筛选相似对象的方法,而不是实际检查每个对象的类型


享受吧

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

public void LoadListFromFile()
{
    // Load logic

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

我想您正在查找
系统中的
of type
。Linq
库:

foreach (Employee e in personList.OfType<Employee>())
{
    Debug.WriteLine(e.salary.toString());
}
foreach (Guest g in personList.OfType<Guest>())
{
    Debug.WriteLine(g.id.toString());
}
foreach(personList.OfType()中的员工e)
{
Debug.WriteLine(如salary.toString());
}
foreach(personList.OfType()中的来宾g)
{
Debug.WriteLine(g.id.toString());
}

我认为在您的特定示例中,继承结构没有增加多少好处,但我离题了

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

在运行某种计算或显示之前,必须事先知道对象的确切类型,这将把计算的责任推到调用代码上。如果您创建第三种类型,则必须更新所有可能的引用,这将给您带来维护噩梦

感觉到如何表示自身的逻辑应该是对象本身的责任(在您的示例中)


这就是overriding
ToString
给您的,然后将表示自身的责任交给最了解的对象(您正在询问的对象)。

这里出了什么问题?你应该填写
类名
人名
。这样做有什么不对。人名=新列表(来源)?我会大肆宣传来回答这个问题,但正如前面的评论所说的那样。糟糕。如果我这样做,我将无法访问class
Employee
Guest
的属性,因为它将是
人员的列表objects@Stmol:在访问所需属性之前,您可以将Person对象强制转换为相应的子类。嘿,Doug,这是有效的C#吗?我以前从来没有在结尾添加演员阵容。有趣。是的,这是一种简单的铸造方法。我也会为你添加另一个更清晰的方法。