C#中判断两个 List<T> 的内容是否相等

news2024/12/27 1:04:17

ET实现游戏中邮件系统逻辑思路(服务端)_游戏邮件系统设计-CSDN博客

场景:今天遇到一个BUG,在服务器重启的时候(体验服),玩家之前接收的邮件又重新接收了一次,但是两封邮件的ID是不同的。ID不同说明玩家自身邮件组件向EmailManager组件拉取了两次,同时也说明EmailManager组件在玩家拉取完邮件后没清理保存,于是我先想着在接受邮件之前判断这个邮件是不是已经接收了。


修复BUG的方式很直接暴力,直接用EmailInfo与玩家自身邮件组件做对比,不过我第一时间想到的竟然是   ‘==’ ,又一次被自己气笑了。 

==运算符对于基本数据类型比较值,对于引用类型默认比较引用(内存地址)。 

由于两封邮件内容、时间、奖励等信息相同但是ID不同那只能比较除ID外的内容是否相等。


 引出正题:

1. 使用 SequenceEqual 方法

System.Linq 命名空间中的 Enumerable.SequenceEqual 方法可以用于比较两个序列的内容是否相等。

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> list1 = new List<int> { 1, 2, 3 };
        List<int> list2 = new List<int> { 1, 2, 3 };
        List<int> list3 = new List<int> { 1, 2, 4 };

        bool areEqual1 = list1.SequenceEqual(list2); // True
        bool areEqual2 = list1.SequenceEqual(list3); // False

        Console.WriteLine($"list1 and list2 are equal: {areEqual1}");
        Console.WriteLine($"list1 and list3 are equal: {areEqual2}");
    }
}

2. 使用 SetEquals 方法

如果你只关心两个集合是否包含相同的元素,而不关心顺序,可以使用 HashSet<T> 的 SetEquals 方法。

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list1 = new List<int> { 1, 2, 3 };
        List<int> list2 = new List<int> { 3, 2, 1 };

        HashSet<int> set1 = new HashSet<int>(list1);
        HashSet<int> set2 = new HashSet<int>(list2);

        bool areEqual = set1.SetEquals(set2); // True,顺序不重要

        Console.WriteLine($"list1 and list2 contain the same elements: {areEqual}");
    }
}

3. 手动比较

如果你需要更复杂的比较逻辑(例如自定义对象),可以手动遍历两个列表并进行比较。

  • 属性 Value:这是一个整型属性,用于存储 MyClass 对象的值。
  • 重写 Equals 方法
    • 该方法用于比较两个 MyClass 对象是否相等。
    • 首先检查传入的对象 obj 是否是 MyClass 的实例。如果是,则比较它们的 Value 属性。
    • 如果 Value 相等,则返回 true,否则返回 false
  • 重写 GetHashCode 方法
    • 该方法返回 Value 属性的哈希码。重写这个方法是为了确保在使用哈希表等数据结构时,MyClass 对象的哈希值是基于其内容的。
using System;
using System.Collections.Generic;

class MyClass
{
    public int Value { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is MyClass other)
        {
            return this.Value == other.Value;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }
}

class Program
{
    static void Main()
    {
        List<MyClass> list1 = new List<MyClass> { new MyClass { Value = 1 }, new MyClass { Value = 2 } };
        List<MyClass> list2 = new List<MyClass> { new MyClass { Value = 1 }, new MyClass { Value = 2 } };

        bool areEqual = list1.Count == list2.Count && !list1.Except(list2).Any(); // True

        Console.WriteLine($"list1 and list2 are equal: {areEqual}");
    }
}
  • 创建 list1 和 list2
    • list1 和 list2 是两个 List<MyClass>,它们各自包含两个 MyClass 对象,Value 分别为 1 和 2
  • 比较两个列表的内容
    • areEqual 变量的值是通过以下逻辑计算得到的:
      • 首先检查两个列表的元素数量是否相等(list1.Count == list2.Count)。
      • 然后使用 Except 方法找出 list1 中不在 list2 中的元素,如果没有这样的元素(即 !list1.Except(list2).Any() 为 true),则说明两个列表的内容相等。
  • 输出结果
    • 最后,使用 Console.WriteLine 输出两个列表是否相等的结果。

总结

  • 使用 SequenceEqual 是最简单和直接的方法,适用于顺序敏感的比较。
  • 使用 SetEquals 适用于无序比较。
  • 手动比较适用于需要自定义比较逻辑的情况。

其实这个修改BUG的方式是很蠢的,还是要从根源上分析为什么会出现两封一样的邮件。


BUG出现的原因

ET框架新起一个服务及实现服务之间的消息通讯_et startsceneconfig-CSDN博客

先说答案:出现这个BUG的原因是线上版本修改了Data服的配置文件(线上版本最开始的配置和本地文件相同,后来修改了Data服的线上版配置文件导致读取数据不一致) 


EmailManager组件放在了自己起的一个服务器Data服上,在SceneFactory添加组件的时候生成的ID和Data服StartSceneConfig@s.xlsx文件配置的ID相同。

比如你本地Data服配置的ID是10,那EmailManager组件保存到MongoDB中的ID也是10。因为修改了线上版本的配置文件,线上Data服配置的ID改为8,那EmailManager组件保存到MongoDB中的ID就多了一个8。

所以数据库中就会有ID为10的数据和ID为8的数据 。

体验服在程序启动的时候把ID为10和8的数据同时拉取了,之后运行过程中又是以ID为8的数据进行保存,所以服务器重启的时候又拉了一遍ID为10的数据造成不一致,让逻辑误以为邮件没领又重新拉了一遍。


解决办法 

解决办法就是在读取和保存数据的时候按照配置文件的ID进行动态操作(本地就用10,线上就用8)

public static async ETTask LoadEmailInfo(this EmailManagerComponent self)
{
    //按照配置文件ID进行读取数据: d.Id == self.DomainScene().Id  (self.DomainScene()是Data)
    var EmailManagerList =  await DBManagerComponent.Instance.GetZoneDB(self.DomainZone()).Query<EmailManagerComponent>(d => true && d.Id == self.DomainScene().Id,collection:"EmailManagerComponent");
           
}


//也可以通过条件: self.DomainScene().Name == "Data"  来筛选你要操作的数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法编程题-优势洗牌

算法编程题-优势洗牌 原题描述方法一、排序二分查找思路简述代码实现复杂度分析 方法二、红黑树思路简述代码实现复杂度分析 方法三、贪心思路简述代码实现复杂度分析 摘要&#xff1a;本文将对LeetCode原题优势洗牌进行介绍&#xff0c;从最容易想到的方法开始&#xff0c;循序…

【从零开始的LeetCode-算法】3264. K 次乘运算后的最终数组 I

给你一个整数数组 nums &#xff0c;一个整数 k 和一个整数 multiplier 。 你需要对 nums 执行 k 次操作&#xff0c;每次操作中&#xff1a; 找到 nums 中的 最小 值 x &#xff0c;如果存在多个最小值&#xff0c;选择最 前面 的一个。将 x 替换为 x * multiplier 。 请你…

ERROR in [eslint] Invalid Options ‘extensions‘ has been removed.

看着这个报错 感觉是版本不对引起的 ERROR in [eslint] Invalid Options: - Unknown options: extensions - extensions has been removed. ERROR in Error: Child compilation failed: [eslint] Invalid Options: - Unknown options: extensions - extensions has b…

SpringCloud书单推荐

重新定义SpringCloud实战 129 疯狂SpringCloud微服务架构实战 SpringBootSpringCloud微服务开发实战 点餐系统 SpringCloud微服务架构实战派 日访问量3000W平台 SpringCloud Alibaba微服务原理与实战 Spring CloudNginx 极简spring cloud实战 Spring Cloud 微服…

试题转excel;试题整理工具;试卷转excel;word转excel

一、问题描述 我父亲是一名教师&#xff0c;偶尔会需要将试卷转excel&#xff0c;方便管理处理一些特别重要的题目 于是&#xff0c;就抽空写一个专门将试题转excel的工具&#xff0c;便于各位教师从业者和教育行业的朋友更好的整理试题&#xff0c;减少一点重复枯燥的工作 …

Node.js Fastify装饰器:提升你的API性能与功能

在Node.js的世界中&#xff0c;Fastify以其卓越的性能和插件化架构脱颖而出&#xff0c;成为构建高效API的首选框架之一。Fastify的装饰器功能&#xff0c;允许开发者以声明式的方式增强和扩展核心对象&#xff0c;如请求&#xff08;Request&#xff09;和响应&#xff08;Res…

数据库管理-第267期 23ai:Oracle Data Redaction演示(20241128)

数据库管理267期 2024-11-286 数据库管理-第267期 23ai&#xff1a;Oracle Data Redaction演示&#xff08;20241128&#xff09;1 示例表及数据2 创建编校策略2.1 名字全编校2.2 电话部分编校 3 DML演示3.1 场景13.2 场景2 总结 数据库管理-第267期 23ai&#xff1a;Oracle Da…

C#VB.Net项目一键多国语言显示

如何在项目什么都不做一键支持多国语言显示 开始我们的一键快捷使用之旅 01.创建多语言项目 02.一键批量窗口开启本地化,添加选中内容添加Mu方法 03.一键快捷翻译 04.运行查看效果 01.创建多语言项目 创建多语言项目前,请先下载安装&#xff0c;注册并登录. 为了便于演示这…

像素流送api ue多人访问需要什么显卡服务器

关于像素流送UE推流&#xff0c;在之前的文章里其实小芹和大家聊过很多&#xff0c;不过今天偶然搜索发现还是有很多小伙伴&#xff0c;在搜索像素流送相关的问题&#xff0c;搜索引擎给的提示有这些。当然这些都是比较短的词汇&#xff0c;可能每个人真正遇到的问题和想获取的…

构建高可用系统设计OpenStack、Docker、Mesos和Kubernetes(简称K8s)

如果构建高可用、高并发、高效运维的大型系统 大型系统架构设计包括业务层设计、服务层设计、基础架层设计、存储层设计、网络层协同设计来完成。 一、业务层 根据主要业务范畴的分类和特征提取&#xff0c;抽象出独立的业务系统&#xff0c;分别统计系统的用户角色群体、访…

零基础Python学习

1.环境搭建 1.1 安装运行环境python3.13 Welcome to Python.org 1.2 安装集成开发环境PyCharm PyCharm: the Python IDE for data science and web development 1.3 创建项目 && 设置字体 2.基础语法 2.1 常量与表达式 在python中整数除整数不会优化&#xff0c;所…

Java Map

Map——广义集合的子集 HashTable是早期Java类库提供的一个哈希表实现&#xff0c;扩展了Dictionary类&#xff0c;类结构上与HashMap明显不同&#xff0c;本身是同步的&#xff0c;不支持null键和值&#xff0c;由于同步导致的性能开销&#xff0c;已经很少被推荐使用。 Hash…

【MySQL — 数据库基础】MySQL的安装与配置 & 数据库简单介绍

数据库基础 本节目标 掌握关系型数据库&#xff0c;数据库的作用掌握在Windows和Linux系统下安装MySQL数据库了解客户端工具的基本使用和SQL分类了解MySQL架构和存储引擎 1. 数据库的安装与配置 1.1 确认MYSQL版本 处理无法在 cmd 中使用 mysql 命令的情况&a…

实测数据处理(BP算法处理)——SAR成像算法系列(九)

系列文章目录 《SAR学习笔记-SAR成像算法系列&#xff08;一&#xff09;》 《后向投影算法&#xff08;BPA&#xff09;-SAR成像算法系列&#xff08;二&#xff09;》 《后向投影算法&#xff08;续&#xff09;-SAR成像算法系列&#xff08;八&#xff09;》 文章目录 一…

(数据结构与算法)如何提高学习算法的效率?面试算法重点有哪些?面试需要哪些能力?

面试官眼中的求职者 通过对你算法的考察&#xff01;&#xff01;&#xff01;&#xff01; 缩进太多&#xff01;&#xff01;一般不要超过三层&#xff01;&#xff01;&#xff01;缩进越少&#xff0c;bug越少&#xff1b;逻辑比较复杂&#xff0c;把这些包装成为函数&…

Day05:缓存双写一致性

redis做为缓存&#xff0c;mysql的数据如何与redis进行同步呢&#xff1f;&#xff08;双写一致性–强一致&#xff09; 一种是一致性要求比较高的同步方案&#xff0c;另一种是允许延迟一致的异步通知。 什么是双写一致性&#xff1f; 双写一致性&#xff1a;当修改了数据库…

vue3+typescript自定义input组件

官方文档&#xff1a;https://cn.vuejs.org/guide/components/events#%E5%AE%9A%E4%B9%89%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6 触发与监听事件​ 在组件的模板表达式中&#xff0c;可以直接使用 $emit 方法触发自定义事件 (例如&#xff1a;在 v-on 的处理函数中)…

代码之丑第一期-缩进

各位小伙伴们,大家好!咱今天就算是正式开张了。实不相瞒,第一期的内容早已写好,但唯独这开篇方式,笔者想了好些时间,包括但不限于如下风格: 斗破苍穹式(已经三刷):代码优雅之力,三段!级别:低级!百年孤独式(困扰于错综复杂的人物关系,放弃):多年以后,面对吐槽…

idea2024加载flowable6.8.1.36遇到的问题-idea启动flowable问题flowable源码启动问题

代码下载地址&#xff1a; https://gitee.com/hanpenghu_admin_admin/flowable6.8.1.git 1.首先是通过顶层目录maven clean install 发现很多子模块并不会install本地mavenStore库&#xff0c;这导致了&#xff0c;一堆相互依赖的模块报错找不到&#xff0c;所以需要根据报错…

Vue.js 中 v-for 指令的三种常见用法详解及key、value、id的作用

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;WebStorm 目录 遍历数组 介绍 代码 遍历对象数组 介绍 代码 遍历对象本身 介绍 代码 效果呈现 key、value、id的作用 1. value 2. key 3. id 在 Vue.js 中&#xff0c…