I have the following linq code.
searchResults = (from item1 in searchResults
join item2 in coll
on item1.skuID equals item2.Skuid
where item2.SearchableValue == value
select item1).ToList();
The variable searchResults is passed in the method as a generic List. The linq segment above filters the list. When returned from the method I expect the list to be开发者_如何转开发 modified but the reference remained unchanged as it was passed in. How do I achieve modifying my reference, not a copy? Thanks.
You should return the filtered result, so if your method looks like this:
public void Filter(List<Item> searchResults)
change it to:
public IEnumerable<Item> Filter(List<Item> searchResults)
and then return the result instead of assigning it to the variable. In other words, change this:
searchResults = (from item1 in searchResults
to this:
return (from item1 in searchResults
In your call, change from:
Filter(list)
to:
list = Filter(list).ToList();
This gives you maximum reusability, as you can pass in a list and trust the method not to change it, leaving the choice whether to place it into a new variable, or replacing the original list, up to you.
Also, as indicated by Fredrik in his comments, the call to .ToList()
in the Linq query should be removed as well, and possible you might want to change the input parameter to be IEnumerable as well.
Let me summarize.
If you have code like this:
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);
and want to make list
become updated, I'd change the code to this:
__ 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();
I see you've already got an answer to your question. But you might be curious as to why you cannot use a ref parameter in a query comprehension.
The reason is because the query comprehension expression represents the query, not its results. It represents a deferred execution of the query. So, suppose we allowed that:
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()) { ... }
}
What does this do? The query is not executed until after Blob returns, but the query refers to a local variable reference on a frame that no longer exists.
The compiler has no way of knowing that you are not in this situation every time a ref is used in a query, so it forbids it entirely.
You're assigning the searchResults
parameter to point to a new List
instance.
To see the change in the calling method, you'll need to make it a ref
parameter.
Alternatively, you could modify the list in-place, like this:
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);
You need to mark the searchResults
parameter as ref
.
public void Foo(ref List<T> searchResults) { ... }
Edit
Since you're using the list in a query (which is an anonymous method), you'll have to modify the list in-place rather than a ref
parameter.
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);
It looks like SLaks got to this answer more quickly.
The variable searchResults
needs to be passed in as a [ref][1]
parameter.
The method signature would look like this.
//Note you only need to ref the one variable.
void filter(ref List searchResults, object otherParameter)
{
//LINQ and stuff here
}
To call it you'll need to use ref
as well:
filter(ref myResults, stuff);
精彩评论