9

IEnumerable.ToList() が新しいリストを作成することになっていることは知っていますが、 ToList()で説明されているように、項目は IEnumerable 内の同じ元の項目を指しています。新しいリストを作成しますか?

ただし、VS 2012 を使用したコードで奇妙な動作が発生しています。WPF; および.NET 4.0。IEnumerable.SequenceEquals() が期待どおりに機能しないように見えたときに始まりました。QuickWatch ダイアログを調べてみたところ、信じられないことに、次のステートメントは false と評価されました。

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

私も試しました:

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

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

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 {

これは、最初に 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 );
        }
    }

何が起こっているのか誰にも分かりますか?下の画像を参照してください。 ここに画像の説明を入力

4

1 に答える 1

7

これから新しいオブジェクトが表示される主な原因は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();
}

これは印刷されますFalse

これが行われるのは、コレクション (.ToList()この場合) を列挙する行為が遅延 LINQ クエリを実行するためです。また、コレクションを 2 回列挙しているため、それを 2 回実行し、同じ値を持つ異なるインスタンスを生成します。

于 2013-08-26T06:59:03.843 に答える