欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# 使用Dictionary復(fù)制克隆副本及比較是否相等

 更新時(shí)間:2020年12月09日 09:44:49   作者:秋漓  
這篇文章主要介紹了C# 使用Dictionary復(fù)制克隆副本及比較是否相等,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

一、復(fù)制克隆

用等號(hào)直接Dictionary1 = Dictionary2,復(fù)制過(guò)去的是地址(賦址),這時(shí)改變Dictionary2,Dictionary1也會(huì)被改變。普遍的是我們常常在改變復(fù)制后的值時(shí)不希望改變?cè)械闹怠_@時(shí)就需要賦值而不是賦址。可用下列方法進(jìn)行賦值:

private void Test()
{
 Dictionary<string, string> dic = new Dictionary<string, string> { { "A", "a" }, { "B", "b" } };
 //方法一
 Dictionary<string, string> dic1 = new Dictionary<string, string>(dic);
 //方法二
 Dictionary<string, string> dic2 = Clone(dic) as Dictionary<string, string>;
 //方法三 --需要引用Newtonsoft.Json.dll
 Dictionary<string, string> dic3 = JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonConvert.SerializeObject(dic2));
}

采用序列化和反序列化

/// <summary>
/// 得到一個(gè)對(duì)象的克隆(二進(jìn)制的序列化和反序列化)--需要標(biāo)記可序列化
/// </summary>
public static object Clone(object obj)
{
 MemoryStream memoryStream = new MemoryStream();
 BinaryFormatter formatter = new BinaryFormatter();
 formatter.Serialize(memoryStream, obj);
 memoryStream.Position = 0;
 return formatter.Deserialize(memoryStream);
}

當(dāng)值為引用類型時(shí)

[Serializable]
public class People : IEquatable<People>
{
 public string Name { get; set; }
 public int Age { get; set; }
 public bool Equals(People other)
 {
  if (other is null)
   return false; 
  return this.Name == other.Name && this.Age == other.Age;
 }
}
 
private void Test()
{
 Dictionary<string, People> dic = new Dictionary<string, People> { { "A", new People {Name="SD",Age=0 } }, { "B", new People { Name = "FD", Age = 1 } } };
 //方法一
 Dictionary<string, People> dic2 = Clone(dic) as Dictionary<string, People>;
 //方法二 --需要引用Newtonsoft.Json.dll
 Dictionary<string, People> dic3 = JsonConvert.DeserializeObject<Dictionary<string, People>>(JsonConvert.SerializeObject(dic2));
}

二、比較兩個(gè)Dictionary是否相等

/// <summary>
/// 比較
/// </summary>
private void Test()
{
 Dictionary<string, object> dic = new Dictionary<string, object> { { "A", 1 }, { "B", "b" } };
 Dictionary<string, object> dic2 = new Dictionary<string, object> { { "A", 1 }, { "B", "b" } };
 var a = dic.Equals(dic2); //結(jié)果 false
 var b = dic.SequenceEqual(dic2); //結(jié)果 true
}

補(bǔ)充知識(shí):C#中的深復(fù)制和淺復(fù)制(在C#中克隆對(duì)象)

C# 支持兩種類型:“值類型”和“引用類型”。

值類型(Value Type)(如 char、int 和 float)、枚舉類型和結(jié)構(gòu)類型。

引用類型(Reference Type) 包括類 (Class) 類型、接口類型、委托類型和數(shù)組類型。

如何來(lái)劃分它們?

以它們?cè)谟?jì)算機(jī)內(nèi)存中如何分配來(lái)劃分

值類型與引用類型的區(qū)別?

1,值類型的變量直接包含其數(shù)據(jù),

2,引用類型的變量則存儲(chǔ)對(duì)象引用。

對(duì)于引用類型,兩個(gè)變量可能引用同一個(gè)對(duì)象,因此對(duì)一個(gè)變量的操作可能影響另一個(gè)變量所引用的對(duì)象。對(duì)于值類型,每個(gè)變量都有自己的數(shù)據(jù)副本,對(duì)一個(gè)變量的操作不可能影響另一個(gè)變量。

值類型隱式繼承自System.ValueType 所以不能顯示讓一個(gè)結(jié)構(gòu)繼承一個(gè)類,C#不支持多繼承

堆棧(stack)是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),在內(nèi)存中,變量會(huì)被分配在堆棧上來(lái)進(jìn)行操作。

堆(heap)是用于為類型實(shí)例(對(duì)象)分配空間的內(nèi)存區(qū)域,在堆上創(chuàng)建一個(gè)對(duì)象,

會(huì)將對(duì)象的地址傳給堆棧上的變量(反過(guò)來(lái)叫變量指向此對(duì)象,或者變量引用此對(duì)象)。

關(guān)于對(duì)象克隆的所設(shè)計(jì)到知識(shí)點(diǎn)

淺拷貝:

是指將對(duì)象中的所有字段逐字復(fù)雜到一個(gè)新對(duì)象

對(duì)值類型字段只是簡(jiǎn)單的拷貝一個(gè)副本到目標(biāo)對(duì)象,改變目標(biāo)對(duì)象中值類型字段的值不會(huì)反映到原始對(duì)象中,因?yàn)榭截惖氖歉北?/p>

對(duì)引用型字段則是指拷貝他的一個(gè)引用到目標(biāo)對(duì)象。改變目標(biāo)對(duì)象中引用類型字段的值它將反映到原始對(duì)象中,因?yàn)榭截惖氖侵赶蚨咽巧系囊粋€(gè)地址

深拷貝:

深拷貝與淺拷貝不同的是對(duì)于引用字段的處理,深拷貝將會(huì)在新對(duì)象中創(chuàng)建一個(gè)新的對(duì)象和原始對(duì)象中對(duì)應(yīng)字段相同(內(nèi)容相同)的字段,也就是說(shuō)這個(gè)引用和原始對(duì)象的引用是不同, 我們改變新

對(duì)象中這個(gè)字段的時(shí)候是不會(huì)影響到原始對(duì)象中對(duì)應(yīng)字段的內(nèi)容。

淺復(fù)制: 實(shí)現(xiàn)淺復(fù)制需要使用Object類的MemberwiseClone方法用于創(chuàng)建一個(gè)淺表副本

深復(fù)制: 須實(shí)現(xiàn) ICloneable接口中的Clone方法,且需要需要克隆的對(duì)象加上[Serializable]特性

namespace DeepCopy
{
 class DrawBase : System.Object, ICloneable
 {
  public List<string> listName = new List<string>();
  public string name = "old";
  public DrawBase()
  {
  } 
  public object Clone()
  {
   //任選一個(gè)
   return this as object;  //引用同一個(gè)對(duì)象
   //return this.MemberwiseClone(); //淺復(fù)制
   //return new DrawBase() as object;//深復(fù)制
  }
 } 
 class Program
 {
  static void Main(string[] args)
  {
   DrawBase rect = new DrawBase();
   Console.WriteLine(rect.name);
   DrawBase line = rect.Clone() as DrawBase;
   line.name = "new";
   line.listName.Add("123");
   Console.WriteLine(rect.name);
   Console.WriteLine(rect.listName.Count);
   Console.ReadLine();
  }
 }
}

當(dāng)return this as object;

輸出:old,new,1

說(shuō)明:方法總是引用同一個(gè)對(duì)象,因此相應(yīng)的堆內(nèi)存上的值會(huì)改變

當(dāng)return this.MemberwiseClone();

輸出:old,old,1

說(shuō)明:對(duì)于內(nèi)部的Class的對(duì)象和數(shù)組,會(huì)Copy地址一份。[從而改變B時(shí),A也被改變了]而對(duì)于其它內(nèi)置的int/string/Enum/struct/object類型,則進(jìn)行值copy。

當(dāng)return new DrawBase() as object;

輸出:old,old,0

說(shuō)明:完全是創(chuàng)建一個(gè)新對(duì)象

總結(jié):

淺拷貝:是指將對(duì)象中的所有字段逐字復(fù)雜到一個(gè)新對(duì)象。

對(duì)值類型字段只是簡(jiǎn)單的拷貝一個(gè)副本到目標(biāo)對(duì)象,改變目標(biāo)對(duì)象中值類型字段的值不會(huì)反映到原始對(duì)象中,因?yàn)榭截惖氖歉北荆?/p>

對(duì)引用型字段則是指拷貝他的一個(gè)引用到目標(biāo)對(duì)象。改變目標(biāo)對(duì)象中引用類型字段的值它將反映到原始對(duì)象中,因?yàn)榭截惖氖侵赶蚨咽巧系囊粋€(gè)地址;

深拷貝:深拷貝與淺拷貝不同的是對(duì)于引用字段的處理,深拷貝將會(huì)在新對(duì)象中創(chuàng)建一個(gè)新的對(duì)象和原始對(duì)象中對(duì)應(yīng)字段相同(內(nèi)容相同)的字段,也就是說(shuō)這個(gè)引用和原始對(duì)象的引用是不同, 我們改變新對(duì)象中這個(gè)字段的時(shí)候是不會(huì)影響到原始對(duì)象中對(duì)應(yīng)字段的內(nèi)容。

以上這篇C# 使用Dictionary復(fù)制克隆副本及比較是否相等就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解析C#設(shè)計(jì)模式之單例模式

    解析C#設(shè)計(jì)模式之單例模式

    這篇文章主要介紹了C#設(shè)計(jì)模式之單例模式的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c# 設(shè)計(jì)模式的內(nèi)容,感興趣的朋友可以了解下
    2020-12-12
  • C#使用DllImport調(diào)用非托管的代碼的方法

    C#使用DllImport調(diào)用非托管的代碼的方法

    C#調(diào)用非托管代碼的方式主要有Com調(diào)用、DllImport方式調(diào)用、加載非托管動(dòng)態(tài)鏈接庫(kù)、直接執(zhí)行機(jī)器碼等方式?,F(xiàn)在介紹一下我自己常用的DllImport方式調(diào)用MSDN中提到的GetShortPathName方法;
    2013-03-03
  • c# richtextbox更新大量數(shù)據(jù)不卡死的實(shí)現(xiàn)方式

    c# richtextbox更新大量數(shù)據(jù)不卡死的實(shí)現(xiàn)方式

    這篇文章主要介紹了c# richtextbox更新大量數(shù)據(jù)不卡死的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • C#實(shí)現(xiàn)利用Windows API讀寫INI文件的方法

    C#實(shí)現(xiàn)利用Windows API讀寫INI文件的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)利用Windows API讀寫INI文件的方法,涉及C#針對(duì)ini文件的創(chuàng)建、讀取及寫入等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • WPF實(shí)現(xiàn)3D立方體波浪墻效果

    WPF實(shí)現(xiàn)3D立方體波浪墻效果

    這篇文章主要為大家詳細(xì)介紹了WPF實(shí)現(xiàn)3D立方體波浪墻效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • C#并發(fā)編程入門教程之概述

    C#并發(fā)編程入門教程之概述

    這篇文章主要給大家介紹了關(guān)于C#并發(fā)編程之概述的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用c#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • C# Socket實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)案例

    C# Socket實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)案例

    這篇文章主要為大家分享了C# Socket簡(jiǎn)單的控制臺(tái)案例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • C# WebService發(fā)布以及IIS發(fā)布

    C# WebService發(fā)布以及IIS發(fā)布

    這篇文章主要介紹了C# WebService發(fā)布以及IIS發(fā)布的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Unity為軟件添加使用有效期的具體步驟

    Unity為軟件添加使用有效期的具體步驟

    今天小編遇到這樣一個(gè)需求需要為軟件設(shè)定一個(gè)使用有效期,當(dāng)超過(guò)指定時(shí)間后,程序無(wú)法執(zhí)行,實(shí)現(xiàn)思路并不復(fù)雜,今天小編通過(guò)本文給大家分享Unity為軟件添加使用有效期的具體步驟,感興趣的朋友一起看看吧
    2022-03-03
  • C# WPF Image控件的綁定方法

    C# WPF Image控件的綁定方法

    這篇文章主要介紹了C# WPF Image控件的綁定方法,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03

最新評(píng)論