2010-12-02 106 views
0

我昨天正在研究一個方法,並遇到了一些奇怪的問題,這裏是代碼的笨拙版本:基本上問題是OrderBy應用於Bar.PopulateList方法不是持久的。將對象傳遞給方法,然後調用該對象的擴展方法


class Foo 
{ 
    List MyObjects; 

    public void PopulateMyObjects() 
    { 
     //Items are added to my list but the OrderBy is not persisting. 
     Bar.PopulateList(MyObjects); 
    } 
} 

class Bar 
{ 
    public static int PopulateList(List theList) 
    { 
     foreach(var in WebSerbiceCall) 
     { 
      theList.Add(var); 
     } 
     // the OrderBy call only sorts 'theList' in the context of this method. 
     // When I return from this method theList has been populated but the Ordering has 
     // reverted back to the order that the items were added to the list. 
     theList.OrderBy(obj => obj.ID); 
     return theList.Count; 
    } 
} 

現在,如果我更新代碼,並添加ref關鍵字按下面的所有作品: 例如public static int PopulateList(ref List List) and Bar.PopulateList(ref MyObjects);

任何人都可以啓發我嗎?我以爲對象總是被ref引用? OrderBy是一種擴展方法嗎?

感謝,慈安

回答

4

這裏的問題是,OrderBy呼叫實際上並不以任何方式變異theList。它會返回一個新的訂購的IEnumerable<object>。因此,這就是爲什麼你沒有看到方法外的調用的影響,它不會改變對象。

使用OrderBy方法會創建一個新值,因此如果您希望調用函數知道這個新值,它必須以某種方式返回。最常見的地方是返回值或參數ref/out

public static int PopulateList(ref List<object> theList) { 
    ... 
    theList = theList.OrderBy(obj => obj.ID).ToList(); 
} 
1

嘗試:

return theList.OrderBy(obj => obj.ID).Count; 

(我要添加一個交代,但@jaredPar解釋它)

+0

有序枚舉是否與未排序列表具有相同數量的元素? – dtb 2010-12-02 00:29:28

+0

OrderBy上面有代碼:theList.Add(var);所以我不認爲這是可以假設的。 – jwwishart 2010-12-02 00:33:30

+0

但OrderBy不添加或刪除任何元素,所以`theList.OrderBy(obj => obj.ID).Count()`應該等於`theList.Count`,否? – dtb 2010-12-02 01:05:19

1

C#通過值傳遞參數,它只是參考類型的值是指向它的內存位置的指針。你遇到的問題是這一行:

theList.OrderBy(obj => obj.ID); 

你不是分配結果:

theList = thisList.OrderBy(obj => obj.ID).ToList(); 
0

如果您不使用ref關鍵字,則傳遞的參數是對同一對象的新引用。從某種意義上說,它是「通過引用傳遞」的,但你必須有點不同地思考。

其他答案都是正確的,OrderBy沒有執行到位,而是返回一個有序集合。但是,如果將參數設置爲結果,則將參數(參考)的值更改爲指向新集合,而不是更改底層對象本身。

例如,

theList = thisList.OrderBy(obj => obj.ID).ToList(); 

需要theList,訂單,然後創建一個新的列表。然後,將theList(它是對列表的引用)的值更改爲指向新創建(排序)的列表。在此方法之外創建的原始引用仍然指向原始無序列表。

原因是,只要你打電話給.ToList()你實際上會創建一個新的列表。當您使用ref關鍵字時,您將包含引用的實際變量傳遞給列表,而不是創建對同一列表的新引用。

相關問題