目前我有一个包含结构的列表,我使用委托在列表中查找结构:
stTest item = myList.Find(delegate(stTest test)
{
return ( string.Compare(test.StringA, somestring, true) == 0 );
});
这对于获取一个项目非常有效,但它似乎返回了它找到的项目的副本,而不是实际的项目,所以如果我修改项目中的字段(我这样做),更新就会消失t对列表中的项目生效。
有没有办法让代理人返回对列表中项目的引用?
答案 0 :(得分: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");
这显然不是一个完美的解决方案,并且确实涉及在扩展方法中复制结构。
真的,如果你需要引用语义,你应该使用引用类型而不是值类型。
答案 1 :(得分:0)
item=myList.FirstOrDefault(entry=>
string.Compare(entry.StringA, someString, true)==0);
请注意,struct不是引用类型,你不能这样做,除非你想把它装入引用类型,但这会带来额外的开销。
如果您真的想使用引用,请考虑使用class重新生成结构。
答案 2 :(得分:0)
如果您将列表成员从struct
更改为class
,它将起作用,因为结构总是被复制。