我有以下linq代码。
searchResults = (from item1 in searchResults
join item2 in coll
on item1.skuID equals item2.Skuid
where item2.SearchableValue == value
select item1).ToList();
变量searchResults作为通用List在方法中传递。上面的linq段过滤列表。当从方法返回时,我希望修改列表但引用在传入时保持不变。如何修改我的引用,而不是副本?感谢。
答案 0 :(得分:12)
您应该返回已过滤的结果,因此如果您的方法如下所示:
public void Filter(List<Item> searchResults)
将其更改为:
public IEnumerable<Item> Filter(List<Item> searchResults)
然后返回结果而不是将其赋值给变量。换句话说,改变这个:
searchResults = (from item1 in searchResults
到此:
return (from item1 in searchResults
在通话中,请改变:
Filter(list)
为:
list = Filter(list).ToList();
这为您提供了最大的可重用性,因为您可以传入一个列表并信任该方法不要更改它,留下选择是将它放入一个新变量,还是替换原始列表,直到您。
此外,正如Fredrik在他的评论中指出的那样,Linq查询中对.ToList()
的调用也应该被删除,并且您可能希望将输入参数更改为IEnumerable。
让我总结一下。
如果你有这样的代码:
public void Filter(List<Item> searchResults)
{
searchResults = (from item1 in searchResults
join item2 in coll
on item1.skuID equals item2.Skuid
where item2.SearchableValue == value
select item1).ToList();
}
...
list = ...
Filter(list);
并希望让list
更新,我会将代码更改为:
__ changed ______ __ changed ______
public IEnumerable<Item> Filter(IEnumerable<Item> searchResults)
{
return from item1 in searchResults <-- changed
join item2 in coll
on item1.skuID equals item2.Skuid
where item2.SearchableValue == value
select item1; <-- changed
}
...
list = ... _ added__
list = Filter(list).ToList();
答案 1 :(得分:7)
我看到你已经得到了问题的答案。但是您可能会对为什么不能在查询理解中使用ref参数感到好奇。
原因是因为查询理解表达式表示查询,而不是其结果。它表示查询的延迟执行。所以,假设我们允许:
IEnumerable<int> Frob(ref int x)
{ return from foo in whatever where foo.bar == x select foo.bar; }
IEnumerable<int> Blob()
{
int y = 123;
var r = Frob(ref y);
y = 456;
return r;
}
void Grob()
{
foreach(int z in Blob()) { ... }
}
这是做什么的?直到Blob返回后才执行查询,但查询引用不再存在的帧上的局部变量引用。
每次在查询中使用ref时,编译器都无法知道你在这种情况下不,所以它完全禁止它。
答案 2 :(得分:4)
您正在指定searchResults
参数以指向新的List
实例。
要查看调用方法的更改,您需要将其设为ref
参数。
或者,您可以就地修改列表,如下所示:
var newResults = (from item1 in searchResults
join item2 in coll
on item1.skuID equals item2.Skuid
where item2.SearchableValue == value
select item1).ToArray();
searchResults.Clear();
searchResults.AddRange(newResults);
答案 3 :(得分:2)
您需要将searchResults
参数标记为ref
。
public void Foo(ref List<T> searchResults) { ... }
修改强>
由于您在查询中使用列表(这是一种匿名方法),因此您必须就地修改列表而不是ref
参数。
var results = (from item1 in searchResults
join item2 in coll
on item1.skuID equals item2.Skuid
where item2.SearchableValue == value
select item1).ToList();
searchResults.Clear();
searchResults.AddRange(results);
看起来SLaks更快地得到了这个答案。
答案 4 :(得分:-2)
变量searchResults
需要作为[ref][1]
参数传递。
方法签名看起来像这样。
//Note you only need to ref the one variable.
void filter(ref List searchResults, object otherParameter)
{
//LINQ and stuff here
}
要调用它,您还需要使用ref
:
filter(ref myResults, stuff);