2015-09-05 18 views
1

我有一些代碼看起來是這樣的:ToList(LINQ)似乎並沒有複製引用

var selectedItems = ItemList.SelectedItems().ToList(); 
var selectedItems2 = ItemList2.SelectedItems().ToList(); 
selectedItems[0] = selectedItems2[0]; 

下面就來看看在SelectedItems擴展方法:

public static IEnumerable<T> SelectedItems<T>(this IEnumerable<T> source) where T : ISelectable 
{ 
    return source.Where(s => s.IsSelected); 
} 

每當我做了ReferenceEquals(ItemList, selectedItems),該值返回false,並且每當我修改任何列表中的值時,更改都不會反映在另一個列表中。

ItemList中的項目是引用類型(自定義類)。

我在做什麼錯?

編輯:

這是原始代碼。我不想過分複雜化的東西,但這裏仍然是:

var test = Map.TileMap.Layers[0].TileList.SelectedItems().ToList(); 
if (ReferenceEquals(test[0], Map.TileMap.Layers[0].TileList[0])) 
{ 
      // returns true  
} 

var tileset2D = Tileset.TileMap.Layers[0].TileList.SelectedItems().To2D(t => t.SelectableRegion.Y).ToList(); 
test[0] = tileset2D[0][0]; 

// test[0] has changed but Tileset.TileMap.Layers[0].TileList[0] hasn't changed. 

這裏的To2D擴展方法:

public static IEnumerable<IEnumerable<T>> To2D<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector) 
{ 
    if (source == null) 
    { 
     throw new ArgumentNullException(nameof(source), "Source collection cannot be null"); 
    } 

    return source.GroupBy(keySelector); 
} 
+0

'ItemList'的來源是什麼? 'IQueryable' /'List '/ etc。? – Caramiriel

+0

列表。 T是可選的。 – CodingMadeEasy

+0

幾乎聽起來像那個列表已經由不同的實體構建而成。在過濾之前確定'ReferenceEquals(ItemList [0],ItemList2 [0])== true'嗎? – Caramiriel

回答

1

調用.ToList()不是鑄造操作。它會生成一個全新的列表對象,並使用.ToList()之前的枚舉結果填充它。引用不一樣,因爲它們是不同的列表。

SelectedItems方法應該返回原始列表的實例。所以你應該能夠測試它的工作原理。

有了這個示例代碼:

var ItemList = new List<Selectable>() 
{ 
    new Selectable() { IsSelected = true }, 
    new Selectable() { IsSelected = false }, 
}; 

var selectedItems = ItemList.SelectedItems().ToList(); 

Console.WriteLine(selectedItems[0].IsSelected); 

ItemList[0].IsSelected = false; 

Console.WriteLine(selectedItems[0].IsSelected); 

我得到的結果:

True 
False 

我的Selectable實現:

public class Selectable : ISelectable 
{ 
    public bool IsSelected { get; set; } 
} 

你必須有東西在代碼中發生的事情,你的避風港沒有顯示。


您已經添加了一些更多的代碼,而現在的這段.GroupBy(t => t.SelectableRegion.Y)讓我覺得,作爲預期分組不工作。您應該測試什麼的分組鍵返回

我的建議,在這一點上,是您避免重新創建擴展方法你的假設。編寫source.Where(s => s.IsSelected).GroupBy(t => t.SelectableRegion.Y)source.SelectedItems().To2D(t => t.SelectableRegion.Y)更好。這種事情只是混淆了代碼,使得更難推理。你所遇到的錯誤種類往往過於頻繁。

+0

但不應該複製以前列表中的參考嗎? – CodingMadeEasy

+0

,因爲ToList()返回新列表(來源) – CodingMadeEasy

+0

@Enigmativity如何返回原始列表的實例?那不是我用Where在做什麼? – CodingMadeEasy

0

的問題是,我是我的列表項

test[0] = tileset2D[0][0]; 

分配一個新的參考所以現在測試[0]是指向在內存中tileset2D相同的地址[0] [0]。這就是爲什麼test [0]中的值不修改Map.TileMap.Layers [0] .TileList中的值。

所以我基本上必須創建一些DeepClone方法的時間,它將複製值並克隆引用,而不會爲我的TileList項目分配新的引用。

感謝您的所有幫助:)