C# 值拷貝、引用拷貝、淺拷貝、深拷貝

值拷貝

定義:直接復制變量的值,適用于基本數據類型(如int, float, char等)。在 C# 中,值類型(基本數據類型和結構體)默認使用值拷貝。

特點:創建原始值的完全獨立副本,修改副本不會影響原始值

示例

int a = 10;
int b = a; // 值拷貝
b = 20;    // 修改b不會影響a

打印:

引用拷貝

?定義:復制對象的引用(內存地址),不創建新對象。對于引用類型(類、接口、委托、數組等),賦值操作默認是引用拷貝。

特點:新變量和原變量指向同一個對象,修改其中任一對象都會影響另一個

示例

class Person { public string Name; }
var person1 = new Person() { Name = "小明" };
var person2 = person1;person2.Name = "小紅";

打印:

淺拷貝

定義:創建一個新的對象。如果數據是基本類型,拷貝的就是基本類型的值;如果數據是引用類型,則拷貝的就是內存地址即引用。

特點

1、修改克隆對象中的基本類型數據不會影響原對象的基本類型數據。

2、修改克隆對象中的引用類型數據會影響原對象的值類型數據,本質上,兩者的引用類型數據是同一個。

示例

class Person : ICloneable
{public string Name;public int Id;public Address Address; // 引用類型字段public object Clone(){return this.MemberwiseClone(); // 淺拷貝}
}class Address { public string Street; }//--------------------------------------------------------Person person1 = new Person { Name = "Alice", Id = 666,Address = new Address { Street = "北京" }
};Person person2 = (Person)person1.Clone();//淺拷貝person2.Name = "Bob"; 
person2.Id = 123;
person2.Address.Street = "上海"; // 會影響p1的Address

打印:

深拷貝

?定義:完全復制原始對象及其所有嵌套對象,創建一個獨立的,全新的對象,在深拷貝中,原始對象與新對象之間沒有任何共享的引用

特點:修改克隆對象中的基本類型數據或者引用類型數據都不會影響原對象的數據,它們是完全獨立的。

示例

class Person : ICloneable
{public string Name;public int Id;public Address Address; // 引用類型字段public object Clone(){Person cloned = (Person)this.MemberwiseClone();cloned.Address = new Address { Street = this.Address.Street }; // 深拷貝引用類型字段return cloned;}
}class Address { public string Street; }//--------------------------------------------------------Person person1 = new Person { Name = "Alice", Id = 666,Address = new Address { Street = "北京" }
};Person person2 = (Person)person1.Clone();//深拷貝person2.Name = "Bob"; 
person2.Id = 123;
person2.Address.Street = "上海"; 

打印:

總結

拷貝類型

實現方法

特點

適用場景

性能

值拷貝

直接賦值

創建完全獨立副本

值類型(int, float, struct等)

引用拷貝

直接賦值

共享同一對象引用

引用類型(class)的簡單傳遞

淺拷貝

MemberwiseClone

復制值類型字段,共享引用類型字段

對象結構簡單或引用字段無需獨立

中等

深拷貝

手動實現/序列化

完全獨立的對象圖

復雜對象需要完全獨立副本

較低

知識補充

對復雜對象使用序列化實現深拷貝

本示例使用Newtonsoft實現,也可以使用其他的序列化方法實現

using Newtonsoft.Json;
class Person : ICloneable
{public string Name;public int Id;public Address Address; // 引用類型字段public object Clone(){string json = JsonConvert.SerializeObject(this);return JsonConvert.DeserializeObject<Person>(json);}
}class Address { public string Street; }
特性序列化方法普通手動方法
實現復雜度簡單,一行代碼處理整個對象圖復雜,需要為每個引用類型字段手動實現
維護成本低,對象結構變化不影響拷貝邏輯高,對象結構變化需同步修改拷貝方法
性能較低(涉及序列化/反序列化開銷)較高(直接內存操作)
循環引用處理自動處理需手動處理,否則會棧溢出
私有字段拷貝可以拷貝私有字段只能拷貝可訪問字段

處理集合類對象的拷貝

淺拷貝

1. 使用構造函數淺拷貝
class Person
{public string Name;public int Id;
}List<Person> originalList = new List<Person> { new Person
{Name = "Alice" ,Id = 111} };List<Person> shallowCopy = new List<Person>(originalList); // 淺拷貝// 修改新集合中的元素會影響原集合
shallowCopy[0].Name = "Bob";
2. 使用 LINQ 的 ToList()/ToArray()實現淺拷貝
class Person
{public string Name;public int Id;
}List<Person> originalList = new List<Person> { new Person
{Name = "Alice" ,Id = 111} };List<Person> shallowCopy = originalList.ToList();// 淺拷貝// 修改新集合中的元素會影響原集合
shallowCopy[0].Name = "Bob";

深拷貝

手動實現

先在Person類中實現深拷貝方法

class Person : ICloneable
{public string Name;public int Id;public Address Address; // 引用類型字段public object Clone(){string json = JsonConvert.SerializeObject(this);return JsonConvert.DeserializeObject<Person>(json);}
}List<Person> originalList = new List<Person> { new Person{Name = "Alice" ,Id = 111} };List<Person> deepCopy = new List<Person>();
foreach (var data in originalList)
{deepCopy.Add((Person)data.Clone());
}deepCopy[0].Name = "Bob";
使用 LINQ + 元素拷貝
 List<Person> deepCopy = originalList.Select(p => (Person)p.Clone()).ToList();

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90399.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90399.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90399.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度學習圖像分類數據集—百種鳥類識別分類

該數據集為圖像分類數據集&#xff0c;適用于ResNet、VGG等卷積神經網絡&#xff0c;SENet、CBAM等注意力機制相關算法&#xff0c;Vision Transformer等Transformer相關算法。 數據集信息介紹&#xff1a;525種鳥類識別分類 訓練數據集總共有84635張圖片&#xff0c;每個文件夾…

零基礎 “入坑” Java--- 八、類和對象(一)

文章目錄一、初識面向對象二、類的定義和使用1.認識類2.類的定義格式三、類的實例化四、this引用五、對象的構造及初始化1.有關初始化2.構造方法3.就地初始化一、初識面向對象 Java是一門純面向對象的語言&#xff08;OOP&#xff09;&#xff0c;在面向對象的世界里&#xff…

數字孿生技術引領UI前端設計新篇章:智能物聯網的深度集成

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;數字孿生與物聯網的共生革命在智能設備爆發式增長的今天&#xff0c;傳統…

代碼審計-shiro漏洞分析

一、關于shiro介紹 簡單講&#xff0c;shiro是apache旗下的一個Java安全框架&#xff0c;輕量級簡單易上手&#xff0c;框架提供很多功能接口&#xff0c;常見的身份認證 、權限認證、會話管理、Remember 記住功能、加密等等。 二、漏洞分析 1.CVE-2019-12422-shiro550 漏洞原理…

EF提高性能(查詢禁用追蹤)(關閉延遲加載)

EF默認是支持延遲加載的&#xff0c;在加載一個表的數據時&#xff0c;會把關聯表的數據一并加載&#xff0c;這樣會影響性能。 一般建議關閉延遲加載可以提高EF加載的性能。還有其他方法提高性能&#xff08;查詢禁用追蹤&#xff09; 如果要實現延遲加載&#xff0c;必須滿足…

Leetcode+JAVA+貪心III

134.加油站在一條環路上有 n 個加油站&#xff0c;其中第 i 個加油站有汽油 gas[i] 升。你有一輛油箱容量無限的的汽車&#xff0c;從第 i 個加油站開往第 i1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發&#xff0c;開始時油箱為空。給定兩個整數數組 gas 和 …

Qt信號與槽機制及動態調用

Qt信號與槽機制及動態調用一、信號與槽1、Qt信號與槽機制概述2、信號與槽的基本使用3、信號與槽的特性4、使用Lambda表達式作為槽5、信號與槽的參數傳遞6、注意事項二、動態調用機制1、基本用法2、示例代碼3、帶參數的調用4、返回值處理5、信號與槽的動態連接6、動態方法調用7、…

K8s系列之:Kubernetes 的 OLM

K8s系列之:Kubernetes 的 OLM 什么是 Kubernetes 的 OLM什么是Kubernetes中的OperatorOLM 的功能OLM 的核心組件OLM優勢OLM 的工作原理OLM 與 OperatorHub 的關系OLM示例場景什么是CRDoperator 和 CRD的關系為什么需要 CRD 和 OperatorCRD定義資源類型DebeziumServer如何使用d…

前端-HTML-day2

目錄 1、無序列表 2、有序列表 3、定義列表 4、表格-基本使用 5、表格-結構標簽 6、表格-合并單元格 7、表單-input基本使用 8、表單-input占位文本 9、表單-單選框 10、表單-上傳多個文件 11、表單-多選框 12、表單-下拉菜單 13、表單-文本域 14、表單-label標簽…

兩種方式清除已經保存的git賬號密碼

方式一隨便選擇一個文件夾&#xff0c;然后鼠標右鍵-》TortoiseGit ->設置選擇已保存的數據-》認證數據-》清除-》點擊確定方式二 控制面板\用戶帳戶\憑據管理器-》windows憑據普通憑據-》找到git信息-》選擇刪除

Using Spring for Apache Pulsar:Message Production

1. Pulsar Template在Pulsar生產者端&#xff0c;Spring Boot自動配置提供了一個用于發布記錄的PulsarTemplate。該模板實現了一個名為PulsarOperations的接口&#xff0c;并提供了通過其合約發布記錄的方法。這些send API方法有兩類&#xff1a;send和sendAsync。send方法通過…

CSS揭秘:10.平行四邊形

前置知識&#xff1a;基本的css變形一、平行四邊形 要實現一個平行四邊形&#xff0c;可以使用CSS的skew變形屬性來傾斜元素。 transform: skewX(-45deg);圖-1顯示容器和內容都出現了傾斜&#xff0c;該如何解決這個問題&#xff1f; 二、嵌套方案 我們通過將內容嵌套 div 并使…

深度學習 必然用到的 線性代數知識

把標量到張量、點積到范數全串起來&#xff0c;幫你從 0 → 1 搭建 AI 數學底座 &#x1f680; 1 標量&#xff1a;深度學習的最小單元 標量 就是一維空間里的“點”&#xff0c;只有大小沒有方向。例如溫度 52 F、學習率 0.001。 記號&#xff1a;普通小寫 x&#xff1b;域&am…

OpenGL ES 紋理以及紋理的映射

文章目錄開啟紋理創建紋理綁定紋理生成紋理紋理坐標圖像配置線性插值重復效果限制拉伸完整代碼在 Android OpenGL ES 中使用紋理&#xff08;Texture&#xff09;可以顯著提升圖形渲染的質量和效率。以下是使用紋理的主要好處&#xff1a; 增強視覺真實感 紋理可以將復雜的圖像…

從金字塔到個性化路徑:AI 正在重新定義學習方式

幾十年來&#xff0c;我們的教育系統始終遵循著一條熟悉的路線&#xff1a; 從小學、初中、高中&#xff0c;再到大學和研究生。這條標準化的路徑&#xff08;K-12 到研究所&#xff09;結構清晰&#xff0c;卻也緩慢。但在當今這個信息爆炸、知識快速更新、個性化需求高漲的時…

產品經理崗位職責拆解

以下是產品經理崗位職責的詳細分解表&#xff0c;涵蓋工作內容、核心動作及輸出成果&#xff1a;崗位職責具體工作內容輸出成果1. 日常版本迭代管理需求分析及PRD產出協調資源推動產品上線- 收集業務/用戶需求&#xff0c;分析可行性及優先級- 撰寫PRD文檔&#xff0c;明確功能…

后端微服務基礎架構Spring Cloud

版本關系 版本發布說明-阿里云Spring Cloud Alibaba官網 選擇 創建項目 創建父項目 什么都不動&#xff0c;創建即可 1) 刪掉沒用的文件 保留 2) pom中加入 打包方式 <packaging>pom</packaging> 3) 刪掉src 4) pom.xml中刪除沒用的 5)更改pom.xml中 spring…

數據分析框架和方法

一、核心分析框架 (The Big Picture Frameworks)??描述性分析 (What Happened?)????目的&#xff1a;?? 了解過去發生了什么&#xff0c;描述現狀&#xff0c;監控業務健康。??核心工作&#xff1a;?? 匯總、聚合、計算基礎指標 (KPI)&#xff0c;生成報表和儀表盤…

電路研究9.3.10——合宙Air780EP中的AT開發指南:阿里云應用指南

這個好像也用不到&#xff0c;不過可以先貼出來。簡單看了一下也沒深入分析&#xff0c;直接扒過來了&#xff0c;感覺涉及到了上位機的學習了。我這下位機的可能用不到&#xff0c;就是貼過來好了。 應用概述 使用 AT 方式連接阿里云分為一機一密和一型一密&#xff0c;其中一…

[Backlog] 核心協調器 | 終端用戶界面(TUI)實現 | 多分支任務沖突解決 | 測試驗證體系

第8章 核心協調器 歡迎回到Backlog.md&#xff01; 在上一章文件系統操作中&#xff0c;我們深入了解了數據物理存儲層面的讀寫機制。本章將聚焦系統的神經中樞——核心協調器。 核心協調器的本質&#xff08;中央決策引擎&#xff09; 如果將Backlog.md視為項目管理團隊&a…