简体   繁体   中英

How to use a delegate to get a reference to an item in a list

Currently I have a list containing structs, and I use a delegate to find a struct in the list as such:

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

This has been working perfectly for getting an item, but it seems that it returns a copy of the item it found and not the actual item, so if I modify fields in the item (which I do), the updates don't take effect on the item in the list.

Is there any way to get the delegate to return a reference to the item in the list?

If you are trying to mutate the object in-place, you can "fake it" with a slightly nicer syntax by employing an extension method like this:

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

The usage would look something like this:

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

This is obviously not a perfect solution, and does involve copying of the struct inside of the extension method.

Really, if you need reference semantics you should be using a reference type instead of a value type.

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

Note that struct is not a reference type, you cannot do that, unless you want to box it into a reference type, but that will bring additional overhead.

If you really want to use reference, consider to repalce your struct with class.

如果将列表成员从struct更改为class ,它将起作用,因为始终会复制结构。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM