C#基础:使用Linq进行简单去重处理(DinstinctBy/反射)

目录

一、示例代码

二、示例输出

三、注意雷点

四、全字段去重封装方法

1.封装

2.示例


一、示例代码

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        // 创建一些示例实体对象
        var people = new List<Person>
        {
            new Person { Name = "Alice", Age = 30, City = "New York" },
            new Person { Name = "Bob", Age = 25, City = "Los Angeles" },
            new Person { Name = "Alice", Age = 30, City = "New York" },//重复的
            new Person { Name = "Charlie", Age = 35, City = "Chicago" },
            new Person { Name = "Alice", Age = 28, City = "San Francisco" }
        };

        // 1. 单字段去重
        var uniqueNameFields = people.DistinctBy(p =>p.Name).ToList();
        Console.WriteLine("指定字段(Name)去重结果,重复则保留第一条:");
        foreach (var person in uniqueNameFields)
        {
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, City: {person.City}");
        }

        // 2. 多字段去重
        var uniqueNameAgeFields = people.DistinctBy(p => new { p.Name, p.Age }).ToList();
        Console.WriteLine("\n指定字段(Name, Age)去重结果,重复则保留第一条:");
        foreach (var person in uniqueNameAgeFields)
        {
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, City: {person.City}");
        }

        //3.全字段去重
        // 通过 GroupBy 按 Name 和 Age 字段去重
        var uniquePeople = people.DistinctBy(p => new { p.Name, p.Age, p.City }).ToList();
        Console.WriteLine("\n全字段去重:");
        foreach (var person in uniquePeople)
        {
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, City: {person.City}");
        }
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
}

二、示例输出

bash 复制代码
指定字段(Name)去重结果,重复则保留第一条:
Name: Alice, Age: 30, City: New York
Name: Bob, Age: 25, City: Los Angeles
Name: Charlie, Age: 35, City: Chicago

指定字段(Name, Age)去重结果,重复则保留第一条:
Name: Alice, Age: 30, City: New York
Name: Bob, Age: 25, City: Los Angeles
Name: Charlie, Age: 35, City: Chicago
Name: Alice, Age: 28, City: San Francisco

全字段去重:
Name: Alice, Age: 30, City: New York
Name: Bob, Age: 25, City: Los Angeles
Name: Charlie, Age: 35, City: Chicago
Name: Alice, Age: 28, City: San Francisco

三、注意雷点

以下代码不能完成全字段去重,因为people是引用类型,Distinct() 一般用于List<string>,List<int>这些值类型去重,而不涉及引用类型的字段比较。

cs 复制代码
people.Distinct().ToList()

若需要全字段去重:1.使用DinstinctBy语法,加上所有字段。2.使用标题四的封装方法(反射实现全字段去重)。

四、全字段去重封装方法

1.封装

cs 复制代码
/// <summary>
/// 通用的全字段去重方法
/// </summary>
/// <returns></returns>
public static IEnumerable<T> DistinctByAllFields<T>(IEnumerable<T> items)
{
    // 获取 T 类型的所有字段值
    var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

    return items
        .GroupBy(item => string.Join(",", properties.Select(p => p.GetValue(item))))  // 按所有字段值连接生成唯一标识符
        .Select(group => group.First());  // 取每组的第一个元素
}

2.示例

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // 创建一些示例实体对象
        var people = new List<Person>
        {
            new Person { Name = "Alice", Age = 30, City = "New York" },
            new Person { Name = "Bob", Age = 25, City = "Los Angeles" },
            new Person { Name = "Alice", Age = 30, City = "New York" },
            new Person { Name = "Charlie", Age = 35, City = "Chicago" },
            new Person { Name = "Alice", Age = 28, City = "San Francisco" }
        };

        // 调用封装的去重方法
        var uniquePeople = DistinctByAllFields(people).ToList();

        Console.WriteLine("根据所有字段去重的结果:");
        foreach (var person in uniquePeople)
        {
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, City: {person.City}");
        }
    }

    /// <summary>
    /// 通用的全字段去重方法
    /// </summary>
    /// <returns></returns>
    public static IEnumerable<T> DistinctByAllFields<T>(IEnumerable<T> items)
    {
        // 获取 T 类型的所有字段值
        var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        return items
            .GroupBy(item => string.Join(",", properties.Select(p => p.GetValue(item))))  // 按所有字段值连接生成唯一标识符
            .Select(group => group.First());  // 取每组的第一个元素
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
}
相关推荐
朝朝辞暮i9 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
小师兄吃牛肉10 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记10 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
未来之窗软件服务10 小时前
C# 截图源码支持自动保存-东方仙盟
c#·仙盟创梦ide·东方仙盟·电脑工具
言乐611 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_3077791311 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha11 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i11 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
朝朝辞暮i11 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
笨笨饿12 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网