2013-08-26 8 views
9

wiem IEnumerable.ToList() ma utworzyć nową listę, ale z elementów wskazujących na tych samych oryginalnych elementów w IEnumerable, jak to omówiono w ToList()-- Does it Create a New List?Dziwne, IEnumerable.ToList() tworzy całkowicie nowe obiekty

Jednak otrzymuję dziwne zachowanie z mojego kodu przy użyciu VS 2012; WPF; i .NET 4.0. Zaczęło się, gdy IEnumerable.SequenceEquals() wydawało się nie działać tak, jak się spodziewałem. I wykopali wokół z mojego okna QuickWatch, a niewiarygodnie, następujące oświadczenie wartość false:

this.Items.First() == this.Items.ToList()[ 0 ] 

Próbowałem nawet:

this.Items.ToList().IndexOf(this.Items.First()) 

które oceniano na -1.

Items jest zadeklarowana jako własność na niestandardowym kontroli WPF, tak jak poniżej:

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);     
    } 
} 

UserLayoutType to po prostu klasa generowane przez narzędzie XSD, z następującym oświadczeniem:

// 
// 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 { 

ten są metody w klasie fabryki, które tworzą elementy UserLayoutType w pierwszej kolejności:

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); 
     } 
    } 

Ktoś ma pojęcie, co się dzieje? Patrz zdjęcie poniżej: enter image description here

+0

cześć, spróbuj użyć metody .Equals, czyli. this.Items.First(). Equals (this.Items.ToList() [0]) – user1778606

+0

Czym są zadeklarowane elementy? Myślę, że najlepiej jest spróbować stworzyć krótki prosty fragment kodu, który pokazuje problemy, o których mówisz. Następnie opublikuj kod w swoim pytaniu. Poza tym musisz nauczyć się różnicy między == a .Equals() – dcaswell

+0

Jaki jest typ środowiska wykonawczego 'this.Items'? Nie ma żadnych przesłonięć na 'Equals' lub' == '? – Blorgbeard

Odpowiedz

7

Głównym, prawdopodobne przyczyny, dlaczego widzisz nowych obiektów z tego jest to, że IEnumerable<T> jest owijanie generator, a nie do zmaterializowanej kolekcję.

Oto prosty LINQPad program wykazać:

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(); 
} 

To będzie drukować False.

Wykona to, ponieważ akt wyliczenia na kolekcji (.ToList() w tym przypadku) wykona odroczone zapytanie LINQ, a ponieważ wyliczamy kolekcję dwukrotnie, wykonujemy ją dwukrotnie, tworząc różne wystąpienia z tym samym wartości.

Powiązane problemy