日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# 实现一个基于值相等性比较的字典

發布時間:2023/12/4 C# 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 实现一个基于值相等性比较的字典 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C# 實現一個基于值相等性比較的字典

Intro

今天在項目里遇到一個需求,大概是這樣的我要比較兩個 JSON 字符串是不是相等,JSON 字符串其實是一個 Dictionary<string, string> 但是順序可能不同,和上一篇 record 使用場景中的第一個需求類似,前面我們介紹過使用 record 可以比較方便的解決,但是我們的項目是 .netcoreapp3.1 的,不能使用 record,如何比較方便的比較呢?我們能否自己實現一個類似于 record 的類型,基于值去比較呢?于是就有了本文的探索

StringValueDictioanry

實現了一個基于值進行比較的字典,實現代碼如下,實現的比較簡單,涉及到一些簡單的知識點,平時不怎么用已經忘了怎么寫了,通過寫下面的代碼又學習了一下

先來看測試代碼吧,測試代碼如下:

[Fact] public?void?EqualsTest() {var?abc?=?new?{?Id?=?1,?Name?=?"Tom"?};var?dic1?=?StringValueDictionary.FromObject(abc);var?dic2?=?StringValueDictionary.FromObject(new?Dictionary<string,?object>(){{"Name",?"Tom"?},{"Id",?1},});Assert.True(dic1?==?dic2);Assert.Equal(dic1,?dic2); }[Fact] public?void?DistinctTest() {var?abc?=?new?{?Id?=?1,?Name?=?"Tom"?};var?dic1?=?StringValueDictionary.FromObject(abc);var?dic2?=?StringValueDictionary.FromObject(new?Dictionary<string,?object>(){{"Id",?1},{"Name",?"Tom"?},});var?set?=?new?HashSet<StringValueDictionary>();set.Add(dic1);set.Add(dic2);Assert.Single(set); }[Fact] public?void?CloneTest() {var?dic1?=?StringValueDictionary.FromObject(new?Dictionary<string,?object>(){{"Id",?1},{"Name",?"Tom"?}});var?dic2?=?dic1.Clone();Assert.False(ReferenceEquals(dic1,?dic2));Assert.True(dic1?==?dic2); }[Fact] public?void?ImplicitConvertTest() {var?abc?=?new?{?Id?=?1,?Name?=?"Tom"?};var?stringValueDictionary?=?StringValueDictionary.FromObject(abc);Dictionary<string,?string>?dictionary?=?stringValueDictionary;Assert.Equal(stringValueDictionary.Count,?dictionary.Count);var?dic2?=?StringValueDictionary.FromObject(dictionary);Assert.Equal(dic2,?stringValueDictionary);Assert.True(dic2?==?stringValueDictionary); }

從上面的代碼可能大概能看出一些實現,重寫了默認的 Equals 和 GetHashCode,并重載了“==” 運算符,并且實現了一個從 StringValueDictionary 到 Dictionary 的隱式轉換,來看下面的實現代碼:

public?sealed?class?StringValueDictionary?:?IEquatable<StringValueDictionary> {private?readonly?Dictionary<string,?string?>?_dictionary?=?new();private?StringValueDictionary(IDictionary<string,?string?>?dictionary){foreach?(var?pair?in?dictionary){_dictionary[pair.Key]?=?pair.Value;}}private?StringValueDictionary(StringValueDictionary?dictionary){foreach?(var?key?in?dictionary.Keys){_dictionary[key]?=?dictionary[key];}}public?static?StringValueDictionary?FromObject(object?obj){if?(obj?is?null)?throw?new?ArgumentNullException(nameof(obj));if?(obj?is?IDictionary<string,?string?>?dictionary){return?new?StringValueDictionary(dictionary);}if?(obj?is?IDictionary<string,?object?>?dictionary2){return?new?StringValueDictionary(dictionary2.ToDictionary(p?=>?p.Key,?p?=>?p.Value?.ToString()));}if?(obj?is?StringValueDictionary?dictionary3){return?new?StringValueDictionary(dictionary3);}return?new?StringValueDictionary(obj.GetType().GetProperties().ToDictionary(p?=>?p.Name,?p?=>?p.GetValue(obj)?.ToString()));}public?static?StringValueDictionary?FromJson(string?json){Guard.NotNull(json,?nameof(json));var?dic?=?json.JsonToObject<Dictionary<string,?object?>>().ToDictionary(x?=>?x.Key,?x?=>?x.Value?.ToString());return?new?StringValueDictionary(dic);}public?StringValueDictionary?Clone()?=>?new(this);public?int?Count?=>?_dictionary.Count;public?bool?ContainsKey(string?key)?=>?_dictionary.ContainsKey(key)???_dictionary.ContainsKey(key)?:?throw?new?ArgumentOutOfRangeException(nameof(key));public?string??this[string?key]?=>?_dictionary[key];public?Dictionary<string,?string>.KeyCollection?Keys?=>?_dictionary.Keys!;public?bool?Equals(StringValueDictionary??other){if?(other?is?null)?return?false;if?(other.Count?!=?Count)?return?false;foreach?(var?key?in?_dictionary.Keys){if?(!other.ContainsKey(key)){return?false;}if?(_dictionary[key]?!=?other[key]){return?false;}}return?true;}public?override?bool?Equals(object?obj){return?Equals(obj?as?StringValueDictionary);}public?override?int?GetHashCode(){var?stringBuilder?=?new?StringBuilder();foreach?(var?pair?in?_dictionary){stringBuilder.Append($"{pair.Key}={pair.Value}_");}return?stringBuilder.ToString().GetHashCode();}public?static?bool?operator?==(StringValueDictionary??current,?StringValueDictionary??other){return?current?.Equals(other)?==?true;}public?static?bool?operator?!=(StringValueDictionary??current,?StringValueDictionary??other){return?current?.Equals(other)?!=?true;}public?static?implicit?operator?Dictionary<string,?string?>(StringValueDictionary?dictionary){return?dictionary._dictionary;} }

More

上述代碼實現的有點粗糙,可能會有一些問題,僅供參考

以上代碼基本實現了基于想要的值的相等性比較以及 Clone(復制、克隆)的目標

實現相等性比較的時候,Equals 和 GetHashCode 方法也要重寫,如果沒有重寫 GetHashCode,編譯器也會給出警告,如果沒有重寫 GetHashCode 在實際在 HashSet 或者 Dictionary 里可能會出現重復 key

重載運算符的時候需要一個靜態方法,"==" 和 "!=" 是一對操作運算符,如果要實現兩個都要實現,不能只實現其中一個

implicit ?也算是一個特殊的運算符,巧妙的使用隱式轉換可以大大簡化代碼的寫法,StackExchange.Redis 中就使用了 implicit 來實現 RedisValue 和 string 等其他常用類型的隱式轉換

References

  • https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Models/StringValueDictionary.cs

  • https://github.com/WeihanLi/WeihanLi.Common/blob/dev/test/WeihanLi.Common.Test/ModelsTest/StringValueDictionaryTest.cs

總結

以上是生活随笔為你收集整理的C# 实现一个基于值相等性比较的字典的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。