0

目前我有一个包含结构的列表,我使用委托在列表中查找结构,如下所示:

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

这对于获取项目非常有效,但似乎它返回的是它找到的项目的副本而不是实际项目,所以如果我修改项目中的字段(我这样做),更新不会生效在列表中的项目上。

有没有办法让委托返回对列表中项目的引用?

4

3 回答 3

2

如果您试图就地改变对象,您可以通过使用如下扩展方法以稍微更好的语法“伪造它”:

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

这显然不是一个完美的解决方案,并且确实涉及在扩展方法内部复制结构。

真的,如果您需要引用语义,您应该使用引用类型而不是值类型。

于 2013-03-21T15:44:26.007 回答
0

struct如果您将列表成员从 更改为,它将起作用class,因为结构总是被复制的。

于 2013-03-21T15:16:18.830 回答
0
item=myList.FirstOrDefault(entry=> 
     string.Compare(entry.StringA, someString, true)==0);

注意 struct 不是引用类型,你不能这样做,除非你想把它装箱成​​引用类型,但这会带来额外的开销。

如果您真的想使用引用,请考虑用类替换您的结构。

于 2013-03-21T15:04:16.483 回答