簡體   English   中英

如何使用委托獲取對列表中項目的引用

[英]How to use a delegate to get a reference to an item in a list

目前我有一個包含結構的列表,我使用委托來查找列表中的結構:

stTest item = myList.Find(delegate(stTest test) 
{
   return ( string.Compare(test.StringA, somestring, true) == 0 );
});

這對於獲取項目一直很有效,但似乎它返回了它找到的項目的副本而不是實際項目,所以如果我修改項目中的字段(我這樣做),更新不會生效在列表中的項目上。

有沒有辦法讓委托返回列表中項目的引用?

如果你試圖就地改變對象,你可以通過采用這樣的擴展方法,用更好的語法“偽造”它:

public delegate void Mutator<T>(ref T arg) where T : struct;

public static void FindAndMutate<T>(
    this IList<T> self,
    Predicate<T> predicate,
    Mutator<T> mutator) where T : struct
{
    if (self == null) { throw new ArgumentNullException("self"); }
    if (predicate == null) { throw new ArgumentNullException("predicate"); }
    if (mutator == null) { throw new ArgumentNullException("mutator"); }

    for (int i = 0; i < self.Count; ++i) {
        var value = self[i];

        if (predicate(value)) {
            mutator(ref value);

            self[i] = value;
        }
    }
}

用法看起來像這樣:

struct AStruct
{
    public string String;
    public int Int;
}

var list = new[] {
    new AStruct() { String = "hello", Int = 0},
    new AStruct() { String = "world", Int = 1}
};

list.FindAndMutate(i => i.Int == 0, (ref AStruct i) => i.String = "goodbye");

這顯然不是一個完美的解決方案,並且確實涉及在擴展方法內部復制struct。

真的,如果你需要引用語義,你應該使用引用類型而不是值類型。

item=myList.FirstOrDefault(entry=> 
     string.Compare(entry.StringA, someString, true)==0);

請注意,struct不是引用類型,您不能這樣做,除非您想將它裝入引用類型,但這會帶來額外的開銷。

如果您真的想使用引用,請考慮使用class重新生成結構。

如果將列表成員從struct更改為class ,它將起作用,因為始終會復制結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM