亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

代碼正在修改錯誤的變量...為什么?

代碼正在修改錯誤的變量...為什么?

C#
弒天下 2022-07-10 16:23:13
我有一件奇怪的事情,我正在做的一些代碼正在修改副本和原始列表。我已經盡可能地將問題歸結為僅在單個文件中顯示錯誤。盡管我在現實世界中的例子要復雜得多.. 但歸根結底,這一切都是問題所在。using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace TestingRandomShit{    class Program    {        private static string rawInput;        private static List<string> rawList;        private static List<string> modifiedList;        static void Main(string[] args)        {            rawInput = "this is a listing of cats";            rawList = new List<string>();            rawList.Add("this");            rawList.Add("is");            rawList.Add("a");            rawList.Add("listing");            rawList.Add("of");            rawList.Add("cats");            PrintAll();            modifiedList = ModIt(rawList);            Console.WriteLine("\n\n**** Mod List Code has been run **** \n\n");            PrintAll();        }        public static List<string> ModIt(List<string> wordlist)        {            List<string> huh = new List<string>();            huh = wordlist;            for (int i = 0; i < huh.Count; i++)            {                huh[i] = "wtf?";            }            return huh;        }基本上,我有三個變量......一個字符串和兩個列表。原始代碼對字符串進行了一些標記,但對于這個演示,我簡單地使用 List.Add() 來偽造它以使其易于閱讀。所以我現在有一個字符串和一個列表,每個元素中都有一個單詞。這是我不明白的令人困惑的部分。我知道它與參考有關,但我不知道如何適應它。有一種方法我稱之為 ModIt()...它簡單地接受一個列表,然后創建一個名為 huh 的全新列表,將原始列表復制到新列表上,然后將 huh 中的每一行更改為“wtf?”?,F在據我了解..我最終應該得到3個變量...1) 一個字符串 2) 一個在每個元素中包含不同單詞的列表 3) 一個與另一個長度相同且每個元素為“wtf?”的列表但是,發生的情況是我嘗試打印出兩個列表,它們都將每個元素都設置為“WTF?”....所以是的.. wtf man?我超級困惑。我的意思是在 ModIt 中,我什至構建了一個全新的字符串,而不是修改正在傳遞的字符串,但它似乎沒有任何影響。這是輸出...: 原始輸入 : 這是貓的列表: Original List : 這是貓的列表**** 模組列表代碼已運行 ****: 原始輸入 : 這是貓的列表: 原始列表 : wtf? 什么?什么?什么?什么?什么?: 修改列表 : wtf? 什么?什么?什么?什么?什么?
查看完整描述

3 回答

?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

huh = wordlist;不會將 的項目復制wordlist到新列表中,它會將引用復制到所占用的同一對象wordlist(即huhwordlist然后指向內存中的同一對象)。

如果您想要一份副本,最簡單的制作方法是使用 LINQ:

List<string> huh = wordlist.ToList();

請注意,這將是一個“淺拷貝”。如果您的列表存儲引用對象,則舊列表和新列表都將存儲對相同對象的引用。

有關值與引用類型的更多信息,請參見此處,如果您需要深度副本,請參見此處。

由于您所做的只是替換列表索引處的值,我想淺拷貝就可以了。


查看完整回答
反對 回復 2022-07-10
?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

約翰已經評論了錯誤代碼:


        List<string> huh = new List<string>();

        huh = wordlist;

在這里您創建一個新列表,然后將其丟棄并將您的參考附加huh到您的舊列表中,因此 huh 和 wordlist 都指的是同一件事..


我只是想指出復制列表的非 LINQ 方式:


        List<string> huh = new List<string>(wordlist);

將舊列表傳遞給新列表的構造函數;list 有一個構造函數,它將對象集合存儲在新列表中


您現在有兩個列表,最初它們都引用相同的字符串,但由于字符串無法更改,如果您開始更改列表中的字符串(而不是僅僅將它們從列表中改組或刪除),將創建新的


如果是一個有價值的觀點;您將有 2 個指向相同對象的列表,因此如果您將來有相同的場景,其中的對象可以更改,并且您在一個列表中更改對象,它也會在另一個列表中更改:


//imagine the list stores people, the age of the first

//person in the list is 27, and we increment it

List1[0].PersonAge++;


//list2 is a different list but refers to the same people objects

//this will print 28

Console.Out.WriteLine(list2[0].PersonAge);

這就是我們所說的淺拷貝


查看完整回答
反對 回復 2022-07-10
?
HUWWW

TA貢獻1874條經驗 獲得超12個贊

您的問題來自這樣一個事實,即在 C# 中我們有引用類型值類型

值類型可以通過直接賦值運算符 ( =) 進行賦值,但對于引用類型則不同。引用類型本身不存儲實際數據,它們在內存中存儲數據所在的位置。就像指針一樣,如果你來自 C 世界。

看看IClonable。另請閱讀Jon Skeet 的參數傳遞,它很好地描述了值和引用類型。


查看完整回答
反對 回復 2022-07-10
  • 3 回答
  • 0 關注
  • 154 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號