C# 使用Dictionary復制克隆副本及比較是否相等
一、復制克隆
用等號直接Dictionary1 = Dictionary2,復制過去的是地址(賦址),這時改變Dictionary2,Dictionary1也會被改變。普遍的是我們常常在改變復制后的值時不希望改變原有的值。這時就需要賦值而不是賦址??捎孟铝蟹椒ㄟM行賦值:
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>
/// 得到一個對象的克隆(二進制的序列化和反序列化)--需要標記可序列化
/// </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);
}
當值為引用類型時
[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));
}
二、比較兩個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); //結果 false
var b = dic.SequenceEqual(dic2); //結果 true
}
補充知識:C#中的深復制和淺復制(在C#中克隆對象)
C# 支持兩種類型:“值類型”和“引用類型”。
值類型(Value Type)(如 char、int 和 float)、枚舉類型和結構類型。
引用類型(Reference Type) 包括類 (Class) 類型、接口類型、委托類型和數(shù)組類型。
如何來劃分它們?
以它們在計算機內存中如何分配來劃分
值類型與引用類型的區(qū)別?
1,值類型的變量直接包含其數(shù)據,
2,引用類型的變量則存儲對象引用。
對于引用類型,兩個變量可能引用同一個對象,因此對一個變量的操作可能影響另一個變量所引用的對象。對于值類型,每個變量都有自己的數(shù)據副本,對一個變量的操作不可能影響另一個變量。
值類型隱式繼承自System.ValueType 所以不能顯示讓一個結構繼承一個類,C#不支持多繼承
堆棧(stack)是一種先進先出的數(shù)據結構,在內存中,變量會被分配在堆棧上來進行操作。
堆(heap)是用于為類型實例(對象)分配空間的內存區(qū)域,在堆上創(chuàng)建一個對象,
會將對象的地址傳給堆棧上的變量(反過來叫變量指向此對象,或者變量引用此對象)。
關于對象克隆的所設計到知識點
淺拷貝:
是指將對象中的所有字段逐字復雜到一個新對象
對值類型字段只是簡單的拷貝一個副本到目標對象,改變目標對象中值類型字段的值不會反映到原始對象中,因為拷貝的是副本
對引用型字段則是指拷貝他的一個引用到目標對象。改變目標對象中引用類型字段的值它將反映到原始對象中,因為拷貝的是指向堆是上的一個地址
深拷貝:
深拷貝與淺拷貝不同的是對于引用字段的處理,深拷貝將會在新對象中創(chuàng)建一個新的對象和原始對象中對應字段相同(內容相同)的字段,也就是說這個引用和原始對象的引用是不同, 我們改變新
對象中這個字段的時候是不會影響到原始對象中對應字段的內容。
淺復制: 實現(xiàn)淺復制需要使用Object類的MemberwiseClone方法用于創(chuàng)建一個淺表副本
深復制: 須實現(xiàn) ICloneable接口中的Clone方法,且需要需要克隆的對象加上[Serializable]特性
namespace DeepCopy
{
class DrawBase : System.Object, ICloneable
{
public List<string> listName = new List<string>();
public string name = "old";
public DrawBase()
{
}
public object Clone()
{
//任選一個
return this as object; //引用同一個對象
//return this.MemberwiseClone(); //淺復制
//return new DrawBase() as object;//深復制
}
}
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();
}
}
}
當return this as object;
輸出:old,new,1
說明:方法總是引用同一個對象,因此相應的堆內存上的值會改變
當return this.MemberwiseClone();
輸出:old,old,1
說明:對于內部的Class的對象和數(shù)組,會Copy地址一份。[從而改變B時,A也被改變了]而對于其它內置的int/string/Enum/struct/object類型,則進行值copy。
當return new DrawBase() as object;
輸出:old,old,0
說明:完全是創(chuàng)建一個新對象
總結:
淺拷貝:是指將對象中的所有字段逐字復雜到一個新對象。
對值類型字段只是簡單的拷貝一個副本到目標對象,改變目標對象中值類型字段的值不會反映到原始對象中,因為拷貝的是副本;
對引用型字段則是指拷貝他的一個引用到目標對象。改變目標對象中引用類型字段的值它將反映到原始對象中,因為拷貝的是指向堆是上的一個地址;
深拷貝:深拷貝與淺拷貝不同的是對于引用字段的處理,深拷貝將會在新對象中創(chuàng)建一個新的對象和原始對象中對應字段相同(內容相同)的字段,也就是說這個引用和原始對象的引用是不同, 我們改變新對象中這個字段的時候是不會影響到原始對象中對應字段的內容。
以上這篇C# 使用Dictionary復制克隆副本及比較是否相等就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
c# richtextbox更新大量數(shù)據不卡死的實現(xiàn)方式
這篇文章主要介紹了c# richtextbox更新大量數(shù)據不卡死的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
C#實現(xiàn)利用Windows API讀寫INI文件的方法
這篇文章主要介紹了C#實現(xiàn)利用Windows API讀寫INI文件的方法,涉及C#針對ini文件的創(chuàng)建、讀取及寫入等操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07
C# WebService發(fā)布以及IIS發(fā)布
這篇文章主要介紹了C# WebService發(fā)布以及IIS發(fā)布的相關資料,感興趣的小伙伴們可以參考一下2016-07-07

