我有一个奇怪的事情,我正在做的一些代码是修改副本和原始列表..我已尽可能地解决问题,只能在单个文件中显示错误.虽然我的现实世界的例子我们要复杂得多......但是根本就是这个问题.
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;
}
//****************************************************************************************************************
//Below is just a print function.. all the action is above this line
public static void PrintAll()
{
Console.WriteLine(": Raw Input :");
Console.WriteLine(rawInput);
if (rawList != null)
{
Console.WriteLine("\n: Original List :");
foreach (string line in rawList)
{
Console.WriteLine(line);
}
}
if (modifiedList != null)
{
Console.WriteLine("\n: Modified List :");
foreach (string wtf in modifiedList)
{
Console.WriteLine(wtf);
}
Console.ReadKey();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我有三个变量......一个字符串和两个List.原始代码对字符串进行了一些标记化处理,但是对于这个演示,我简单地使用List.Add()来伪造它以使其易于阅读.
所以我现在有一个字符串和一个List,每个元素中都有一个单词.
这是我不理解的令人困惑的部分..我知道它与引用有关但我无法弄清楚如何适应它.
有一个我称之为ModIt()的方法...它简单地接受一个List然后创建一个名为huh的全新List,将原始列表复制到新列表中,然后将huh中的每一行更改为"wtf?".
现在据我所知..我应该最终得到3个变量......
1)字符串2)每个元素中具有不同单词的List 3)与另一个元素长度相同的列表,每个元素为"wtf?"
但是,会发生什么呢?我试图打印出两个列表,他们将每个元素都设置为"WTF?"....所以是啊.. wtf man?我非常困惑.我的意思是在ModIt中我甚至构建了一个完整的新字符串,而不是修改一个正在通过的字符串,但它似乎没有任何效果.
这是输出......
:Raw Input:这是猫的列表
:原始列表:这是猫的列表
****Mod List Code已经运行****
:Raw Input:这是猫的列表
:原始清单:wtf?跆拳道?跆拳道?跆拳道?跆拳道?跆拳道?
:修改清单:wtf?跆拳道?跆拳道?跆拳道?跆拳道?跆拳道?
Joh*_*ica 12
huh = wordlist;没有的项目复制wordlist到一个新的列表,它复制引用由住在同一对象wordlist(即huh和wordlist然后指向内存中的同一个对象).
如果你想要一个副本,最简单的方法就是使用LINQ:
List<string> huh = wordlist.ToList();
Run Code Online (Sandbox Code Playgroud)
请注意,这将是一个"浅拷贝".如果列表存储引用对象,则旧列表和新列表都将存储对相同对象的引用.
见这里的价值更多的雷丁VS引用类型,然后在这里,如果你需要一个深层副本.
既然你所做的只是替换列表索引处的值,我想一个浅的副本就可以了.
John已经对错误代码发表了评论:
List<string> huh = new List<string>();
huh = wordlist;
Run Code Online (Sandbox Code Playgroud)
在这里你制作一个新的列表,然后扔掉它并附上你对huh旧列表的引用,所以huh和wordlist都指的是同一个东西.
我只是想指出非LINQ复制列表的方式:
List<string> huh = new List<string>(wordlist);
Run Code Online (Sandbox Code Playgroud)
将旧列表传递给新列表的构造函数; 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);
Run Code Online (Sandbox Code Playgroud)
这就是我们所说的浅拷贝
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |