C# DistinctBy与Distinct的区别

你想了解在C#中对反序列化得到的Vehicle列表使用DistinctByDistinct方法的核心区别,尤其是在按字段去重场景下两者的行为差异。

一、核心区别详解

首先需要明确:这两个方法都是LINQ中用于去重的方法,但去重的判断逻辑和使用方式完全不同,结合你的代码场景逐一说明:

1. 先补全必要的Vehicle类定义

你的代码中用到了Vehicle类,但未展示定义,先补充完整(保证代码可运行):

 using DistinctDemo;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;

// 补全Vehicle类定义
namespaceDistinctDemo
{
public class Vehicle
    {
        [JsonProperty("number")]
public string Number { getset; }

        [JsonProperty("vehicleNo")]
public string VehicleNo { getset; }

        [JsonProperty("statusEnum")]
public int StatusEnum { getset; }

        [JsonProperty("status")]
public string Status { getset; }

        [JsonProperty("createdDateTime")]
public DateTime CreatedDateTime { getset; }
    }
}

Console.WriteLine("Hello, World!");
var json = $"

[

        {

            "number""202601210010",

            "vehicleNo""鲁H232H0",

            "statusEnum"1,

            "status""厂外",

            "createdDateTime""2026-01-21T11:42:56.060242"

        },

        {

            "number""202601210010",

            "vehicleNo""鲁H232H0",

            "statusEnum"1,

            "status""厂外",

            "createdDateTime""2026-01-21T11:42:56.060242"

        },

        {

            "number""202601210010",

            "vehicleNo""鲁H232H0",

            "statusEnum"1,

            "status""厂外",

            "createdDateTime""2026-01-21T11:42:56.060242"

        },

        {

            "number""202601210010",

            "vehicleNo""鲁H232H0",

            "statusEnum"1,

            "status""厂外",

            "createdDateTime""2026-01-21T11:42:56.060242"

        },

        {

            "number""202601210010",

            "vehicleNo""鲁H232H0",

            "statusEnum"1,

            "status""厂外",

            "createdDateTime""2026-01-21T11:42:56.060242"

        },

        {

            "number""202601210011",

            "vehicleNo""鄂B5B818",

            "statusEnum"1,

            "status""厂外",

            "createdDateTime""2026-01-21T12:48:24.246919"

        }

    ]

";

var vehicles = JsonConvert.DeserializeObject<List<Vehicle>>(json);

// 按Number字段去重
var v2 = vehicles.DistinctBy(r => r.Number).ToList();
// 默认按对象实例去重(无效果)
var v3 = vehicles.Distinct().ToList();

Console.WriteLine($"原列表数量:{vehicles.Count}"); // 输出 6
Console.WriteLine($"DistinctBy去重后数量:{v2.Count}"); // 输出 2(202601210010 和 202601210011)
Console.WriteLine($"Distinct去重后数量:{v3.Count}"); // 输出 6(无去重效果)

2. Distinct() 方法

  • 核心逻辑 :判断整个对象是否完全相等,默认规则:
    • 对于值类型(如int、string):按“值”相等判断;
    • 对于自定义引用类型(如Vehicle):按“引用地址”相等判断(即只有同一个对象实例才会被判定为重复)。
  • 你的场景表现 :你反序列化得到的6个Vehicle对象都是独立的实例(即使字段值完全相同),所以Distinct()会认为所有对象都不重复,最终返回6个对象,无去重效果
  • 要让Distinct按字段去重 :必须自定义相等逻辑(重写EqualsGetHashCode,或传入IEqualityComparer<Vehicle>),示例:
     // 自定义比较器:按Number字段判断相等
    public class VehicleNumberComparer : IEqualityComparer<Vehicle>
    {
    public bool Equals(Vehicle x, Vehicle y){
    if (x == null || y == nullreturnfalse;
    return x.Number == y.Number;
        }

    public int GetHashCode(Vehicle obj){
    return obj.Number.GetHashCode();
        }
    }

    // 使用自定义比较器的Distinct
    var v4 = vehicles.Distinct(new VehicleNumberComparer()).ToList();
    Console.WriteLine($"自定义Distinct去重后数量:{v4.Count}"); // 输出 2

3. DistinctBy<TKey>() 方法

  • 核心逻辑 :.NET 6+ 新增方法,允许指定一个键选择器(Key Selector),按“指定字段/属性的值”去重,无需修改Vehicle类或自定义比较器。
  • 你的场景表现 DistinctBy(r => r.Number) 会提取每个VehicleNumber字段,只要Number值相同就判定为重复,最终只保留每个Number的第一个对象,所以返回2个对象(202601210010 和 202601210011)。
  • 灵活性 :可按任意字段/组合字段去重,比如按Number + VehicleNo组合去重:
     var v5 = vehicles.DistinctBy(r => $"{r.Number}_{r.VehicleNo}").ToList(); 

二、关键差异对比表

特性 Distinct() DistinctBy()
去重依据 整个对象的相等性(默认按引用) 指定字段/属性的键值
.NET 版本要求 所有版本 .NET 6+
使用复杂度 需自定义比较器(按字段去重时) 直接指定键选择器,简洁易用
你的代码执行结果 返回6个对象(无去重) 返回2个对象(按Number去重)

总结

  1. Distinct()  是“对象级去重”,默认比较引用,按字段去重需自定义相等逻辑,适配所有.NET版本;
  2. DistinctBy()  是“字段级去重”,.NET 6+ 新增,通过键选择器直接指定去重字段,无需修改实体类,使用更简洁;
  3. 在你的场景中,要按Number去重,DistinctBy(r => r.Number) 是最优选择(无需额外代码),而Distinct() 默认无效果,需自定义比较器才能实现相同效果。

本文使用 文章同步助手 同步

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容