prm*_*mph 9 c# ienumerable list .net-4.0
我知道IEnumerable.ToList()应该创建一个新的List,但是项目指向IEnumerable中的相同原始项,如ToList()所述 - 它是否创建一个新列表?
但是,我使用VS 2012的代码得到了一些奇怪的行为; WPF; 和.NET 4.0.它开始于IEnumerable.SequenceEquals()似乎没有像我预期的那样工作.我在我的QuickWatch对话框中挖掘,令人难以置信的是,以下语句的计算结果为false:
this.Items.First () == this.Items.ToList ()[ 0 ]
Run Code Online (Sandbox Code Playgroud)
我甚至尝试过:
this.Items.ToList ().IndexOf(this.Items.First ())
Run Code Online (Sandbox Code Playgroud)
评价为-1.
Items 在WPF自定义控件上声明为属性,如下所示:
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register (
"Items",
typeof ( IEnumerable<UserLayoutType> ),
typeof ( UserLayoutSelectorControl ),
new FrameworkPropertyMetadata ( null, FrameworkPropertyMetadataOptions.AffectsRender, UserLayoutSelectorControl.PropertyChanged ) );
public IEnumerable<UserLayoutType> Items
{
get
{
return ( IEnumerable<UserLayoutType> ) this.GetValue ( UserLayoutSelectorControl.ItemsProperty );
}
set
{
this.SetValue ( UserLayoutSelectorControl.ItemsProperty, value );
}
}
Run Code Online (Sandbox Code Playgroud)
UserLayoutType只是XSD工具生成的类,具有以下声明:
//
// This source code was auto-generated by xsd, Version=4.0.30319.17929.
//
namespace MyAssays.UserLayoutCore.UserLayoutUtility {
using System.Xml.Serialization;
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute("UserLayout", Namespace="", IsNullable=false)]
public partial class UserLayoutType {
Run Code Online (Sandbox Code Playgroud)
这是工厂类中首先创建UserLayoutType项的方法:
public static IEnumerable<UserLayoutType> CreateFromFolder ( string folderPath )
{
if (String.IsNullOrEmpty(folderPath))
throw new ArgumentNullException("folderPath", "Folder path must not be null");
var userLayoutXmlFilePaths = Directory.GetFiles ( folderPath ).Where ( filePath => filePath.EndsWith ( ".UserLayout.xml", StringComparison.InvariantCultureIgnoreCase ) );
return userLayoutXmlFilePaths.Select(filePath => UserLayoutFactory.CreateFromFile(filePath));
}
public static UserLayoutType CreateFromFile ( string filePath )
{
using ( var stream = new StreamReader ( filePath ) )
{
return ( UserLayoutType ) new XmlSerializer ( typeof ( UserLayoutType ) ).Deserialize ( stream );
}
}
Run Code Online (Sandbox Code Playgroud)
有人知道发生了什么吗?见下图:

你从这里看到新物体的主要可能原因IEnumerable<T>是包装了一个发生器,而不是物化的集合.
这是一个简单的LINQPad程序来演示:
void Main()
{
IEnumerable<string> collection =
from index in Enumerable.Range(1, 10)
select "Index=" + index;
var list1 = collection.ToList();
var list2 = collection.ToList();
ReferenceEquals(list1[0], list2[0]).Dump();
}
Run Code Online (Sandbox Code Playgroud)
这将打印False.
它会这样做,因为枚举集合的行为(.ToList()在这种情况下)将执行延迟的LINQ查询,并且因为我们枚举集合两次,所以我们执行它两次,产生具有相同值的不同实例.