C# --- 合并两个列表并将重复项放入一个新列表然后打印该列表

C# --- Merging two lists and taking the duplicates into a new list then printing that list

    {
        public static List<string> DuplicateNames(List<Person> a, List<Person> b)
        {
            List<string> DuplicatePeople = a.Intersect(b).ToList();
        }

        public static void Main(string[] args)
        {
            List<Person> personsA = new List<Person>();
            personsA.Add(new Person("Emma"));
            personsA.Add(new Person("Eva"));
            personsA.Add(new Person("Data"));
            List<Person> personsB = new List<Person>();
            personsB.Add(new Person("Anna"));
            personsB.Add(new Person("Eva"));
            personsB.Add(new Person("Emma"));

            List<string> myDuplicateNames = Program.DuplicateNames(personsA, personsB);

            foreach (String s in myDuplicateNames)
            {
                Console.WriteLine(s);
           }

            Console.Read();
        }
    }
    class Person
    {
        private string name;

        public Person(string name)
        {
            Name = name;
        }

        public string Name { get => name; set => name = value; }

    }

正如标题所说,我正在尝试将列表 personA 和 personB 合并到一个具有函数“DuplicateNames”的新列表中。然后我想调用该函数,它将新列表中的重复名称放入“myDuplicateNames”并打印该列表。

我是 C# 的新手,无法让它工作。如有任何帮助,我们将不胜感激!

您的代码可以修改为与您当前使用的 Intersect 方法一起使用。问题是在您的实现中,您尝试比较您创建的 class:Person。默认情况下,比较是通过引用而不是通过属性的内容进行的。为了使其正常工作,您可以在 Person class:

上覆盖 Equals
class Person
{
    private string name;

    public Person(string name)
    {
        Name = name;
    }

    public string Name { get => name; set => name = value; }

    public override bool Equals(object obj)
    {
        return obj is Person person &&
                name == person.name &&
                Name == person.Name;
    }            
}

关于你的 DuplicateNames 方法的另一个注意事项,应该修改它做你想做的事,将重复的 Person 列表转换为重复的 string 列表使用Select方法:

public static List<string> DuplicateNames(List<Person> a, List<Person> b)
{
    return a.Intersect(b).Select(p => p.Name).ToList();
}

第一个问题:a 是一个人的列表,你试图将它分配给一个字符串列表。 第二个问题:2个同名的人不相等。您可以覆盖 Equals,但 LINQ 为您提供了一种更灵活的方式。

    public class Person
    {
        public string Name { get; }   // Read-only default property, initialized in constructor.

        public Person(string name)
        {
            Name = name;
        }
    }

    public class Program
    {
        public static List<string> DuplicateNames(List<Person> a, List<Person> b)
        {
            // LINQ 1:
            List<string> duplicatePeople = a
                .Select(a => a.Name)                              // Projecting a list of persons to a list of strings
                .Where(a => b.Select(p => p.Name).Contains(a))   // Check for each item if it's in the list of names of b.
                .ToList();  

            // LINQ 2: Join
            var duplicatePeople2 = a.Join(
                    b,                                    // 2nd List
                    a => a.Name,                          // What ist the key of the first list?
                    b => b.Name,                          // What ist the key of the second list?
                    (a, b) => a)                          // Secting the item of the first list (if you have more properties in class Person, this could be different from the item of the second list)
                .Select(p => p.Name)                      // Again: projecting to a list of strings
                .ToList();
            return duplicatePeople;
        }

        public static void Main(string[] args)
        {
            // List offers an initializer.
            var personsA = new List<Person>()
            {
                new Person("Emma"),
                new Person("Eva"),
                new Person("Data")
            };

            var personsB = new List<Person>()
            {
                new Person("Anna"),
                new Person("Eva"),
                new Person("Emma")
            };

            List<string> myDuplicateNames = DuplicateNames(personsA, personsB);

            foreach (var s in myDuplicateNames)
            {
                Console.WriteLine(s);
            }

            Console.Read();
        }
    }