根据参数筛选对象列表

时间:2018-05-03 03:23:50

标签: c# oop generics

class Officer
{
    Person person;
}

class Person
{
    string name;
} 

假设我有一份警官名单和一份人员名单。我想根据一些标准过滤这两个列表。

所以我写了这个方法:

public List<Person> filterName(List<Person> list)
{
   // some filter logic
}

我以下列方式对这两个列表使用此方法:

main()
{
     ...
     List<Officer> officers = Initialize();
     List<Person> validNames= filterNames(officers.Select(o=>o.person.name).ToList())
     foreach (var officer in officers)
     {
          if (!validNames.Contains(officer.Person.name))
                 officers.remove(officer);
     }
     // finally I have a valid set of officers here

     List<Person> persons = Initialize();
     var filteredPersons = filterNames(persons.Select(o=>o.name).ToList())
}

有没有一种使用泛型的好方法,所以我可以避免main方法()中的以下代码?

 List<string> validNames = filterNames(officers.Select(o=>o.fullName).ToList())
 foreach (var officer in officers)
 {
      if (!validNames.Contains(officer.name))
             officers.remove(officer);
 }

并使用泛型以某种方式使用泛型更新人员列表。

2 个答案:

答案 0 :(得分:3)

基于最近编辑的新答案:

var officers = new List<Officer>
{
    new Officer { Name = "Officer Foo" },
    new Officer { Name = "Officer Bar" }
};

officers.RemoveAll(o => o.Name.Contains("Bar"));
// Officers now only contains "Officer Foo"

------------ 旧答案 ----------------

您可以在此处使用OOP并从共同点中获取PersonOfficer吗?

如果是这样,那么你可以轻松地使用它们的公共属性并对其进行过滤,而不是编写两个独立的逻辑来处理它们。

static void Main(string[] args)
{
    var officers = new List<Officer>
    {
        new Officer { Name = "Officer Foo" },
        new Officer { Name = "Officer Bar" }
    };

    var workers = new List<Worker>
    {
        new Worker { Name = "Worker Foo" },
        new Worker { Name = "Worker Bar" }
    };

    var people = workers.Cast<IPerson>().Concat(officers);
    var filteredPeople = Program.Filter(people, "Foo");

    Console.ReadKey(true);
}

static IEnumerable<IPerson> Filter(IEnumerable<IPerson> people, string keyword)
{
    return people.Where(p => p.Name.Contains(keyword));
}

interface IPerson
{
    string Name { get; set; }
}

class Officer : IPerson
{
    public string Name { get; set; }
}

class Worker : IPerson
{
    public string Name { get; set; }
}

答案 1 :(得分:2)

好的,我们假设您有一些复杂的FilterNames函数在列表中运行,您的目标是根据某些Person条件过滤掉。我会像这样重写过滤器:

public bool FilterPerson(Person p)
{
    //Some complicated logic
    //Returns true if person should be kept
    //Returns false if the person should be rejected
}

现在您可以在Linq语句中使用它:

var officers = Initialize().Where(o => FilterPerson(o.Person)).ToList();

无需从列表中删除项目。您仍然可以使用临时对象,它只需要一个额外的步骤:

var officers = Initialize();    //Returns List<Officer>
var filteredOfficers = officers.Where(o => FilterPerson(o.Person)).ToList();