我今天遇到了一个非常奇怪的问题:
基本上,我想使用以下行将一种类型的数组转换为另一种类型的数组:
DirectoryInfo Source = new DirectoryInfo(@"C:\Orpheus_Music");
FileInfo[] Files = Source.GetFiles("*.mp3");
List<MusicFileModel> FileList = new List<MusicFileModel>();
MusicFileModel temp = new MusicFileModel();
foreach (FileInfo file in Files)
{
temp.Name = file.Name.ToString();
temp.Pfad = file.DirectoryName.ToString();
FileList.Add(temp);
Debug.WriteLine(temp.Name + ", " + temp.Pfad);
}
Debug.WriteLine("_______________");
foreach (MusicFileModel file in FileList)
{
Debug.WriteLine(file.Name + ", " + file.Pfad);
}
但是,这不是获取Name和Pfad值的精确副本,而是输出:
01 Rolling in the Deep.mp3, C:\Orpheus_Music
02 Rumour has it.mp3, C:\Orpheus_Music
03 Turning Tables.mp3, C:\Orpheus_Music
04 Don't you remember.mp3, C:\Orpheus_Music
05 Set Fire to the Rain.mp3, C:\Orpheus_Music
06 He won't go.mp3, C:\Orpheus_Music
07 Take it all.mp3, C:\Orpheus_Music
08 I'll be waiting.mp3, C:\Orpheus_Music
09 One and only.mp3, C:\Orpheus_Music
10 Lovesong.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
_______________
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
11 Someone like you.mp3, C:\Orpheus_Music
这里出了什么问题?坦率地说,这似乎是一个初学者的问题,但是,我无法找出究竟是什么导致这一问题。
感谢您的帮助! Michael Heribert
答案 0 :(得分:10)
你每次都在循环中更新同一个对象,所以你最终得到List<T>
中对象的相同副本,最后它只包含在最后一次迭代中设置的值,你必须在循环中实例化新对象,然后将其添加到List<T>
:
foreach (FileInfo file in Files)
{
MusicFileModel temp = new MusicFileModel(); // note this
temp.Name = file.Name.ToString();
temp.Pfad = file.DirectoryName.ToString();
FileList.Add(temp);
Debug.WriteLine(temp.Name + ", " + temp.Pfad);
}
你也可以使用Linq Select()
使其变得更简单,但是需要更多操作,因此对于性能而言,每个循环的简单性更好,但你也可以通过以下方式实现:
FileList = Source.GetFiles("*.mp3")
.Select(file => new MusicFileModel()
{
Name = file.Name.ToString(),
Pfad = file.DirectoryName.ToString()
}).ToList();
答案 1 :(得分:1)
你是对的,这是一个相当新鲜的事情,但当你长时间盯着它时也容易错过
你的问题很简单
MusicFileModel temp = new MusicFileModel();
foreach (FileInfo file in Files)
{
temp.Name = file.Name.ToString();
temp.Pfad = file.DirectoryName.ToString();
FileList.Add(temp);
Debug.WriteLine(temp.Name + ", " + temp.Pfad);
}
你创建了一个名为temp的对象,你所做的就是改变它的值并重新添加到列表中,因此它有11个(ish)同一个对象的条目
将第一行移动到循环中。
foreach (FileInfo file in Files)
{
MusicFileModel temp = new MusicFileModel();
temp.Name = file.Name.ToString();
temp.Pfad = file.DirectoryName.ToString();
FileList.Add(temp);
Debug.WriteLine(temp.Name + ", " + temp.Pfad);
}
您的代码现在可以按预期工作
答案 2 :(得分:1)
我用两个班轮Linq解决问题的两分钱
List<MusicFileModel> FileList;
FileList = Files.Select(x => new MusicFileModel()
{
Name = x.Name, Pfad = x.DirectoryName
}).ToList();
您的错误原因在其他答案中都有详细记录。 正如大家告诉你的那样,更改同一个实例的属性并将其添加到列表n次意味着你的列表有n个对同一个对象的引用。
在我的示例中,Select IEnumerable扩展指示为Files列表中包含的每个FileInfo对象创建一个新的MusicFileModel实例。最后,所有这些实例都在最终的ToList()调用中实现。