中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

C#怎樣實現一個基于值相等性比較的字典-創(chuàng)新互聯

這篇文章主要介紹C#怎樣實現一個基于值相等性比較的字典,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

10年專注建站、設計、互聯網產品按需網站設計服務,業(yè)務涵蓋高端網站設計、成都商城網站開發(fā)、微信小程序、軟件系統(tǒng)開發(fā)、成都app開發(fā)等。憑借多年豐富的經驗,我們會仔細了解每個客戶的需求而做出多方面的分析、設計、整合,為客戶設計出具風格及創(chuàng)意性的商業(yè)解決方案,創(chuàng)新互聯更提供一系列網站制作和網站推廣的服務,以推動各中小企業(yè)全面信息數字化,并利用創(chuàng)新技術幫助各行業(yè)提升企業(yè)形象和運營效率。

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);
}

從上面的代碼可能大概能看出一些實現,重寫了默認的EqualsGetHashCode,并重載了“==” 運算符,并且實現了一個從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(復制、克?。┑哪繕?/p>

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

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

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

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#怎樣實現一個基于值相等性比較的字典”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注創(chuàng)新互聯行業(yè)資訊頻道!

本文標題:C#怎樣實現一個基于值相等性比較的字典-創(chuàng)新互聯
分享鏈接:http://www.rwnh.cn/article36/ehcpg.html

成都網站建設公司_創(chuàng)新互聯,為您提供搜索引擎優(yōu)化、標簽優(yōu)化、移動網站建設、微信小程序、靜態(tài)網站、網站營銷

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

綿陽服務器托管
高安市| 阳江市| 黄龙县| 桃园市| 兴和县| 南部县| 辽阳市| 平陆县| 靖江市| 贡山| 特克斯县| 甘孜县| 赤城县| 天峨县| 红桥区| 永修县| 桦南县| 靖宇县| 囊谦县| 布尔津县| 黑山县| 茶陵县| 锡林郭勒盟| 廊坊市| 怀集县| 华坪县| 禹州市| 古交市| 南溪县| 宿迁市| 溧阳市| 延长县| 柳河县| 河源市| 稻城县| 蓬溪县| 公安县| 永平县| 桐柏县| 怀集县| 建阳市|