Here is my code
class Student
{
some code
}
static class Filter
{
static void TypeFilter(this List<Student> result, string type)
{
result = result.FindAll(x=>x.type == type);
}
}
when I use this extension method like
List<Student> a = some code;
a.TypeFilter("someType");
List a was not filtered, List should be a reference type, then why a didn't change, did I do anything wrong ?
Here's why you;re not seeing the results:
static void TypeFilter(this List<Student> result, string type)
{
result = result.FindAll(x=>x.type == type);
}
List<Student> a = some code;
a.TypeFilter("someType");
Parameters by defualt are passed by value. result
is now a local variable that references a list. When you call FindAll
- you get back a new reference - the original list that result
(and a
) reference is unchanged.
When you reassign the result bask to result
, result
now references the new object, and the link back to a
is broken. a
is unchanged through all of this.
Most Linq methods return a new object instead of modifying the passed in object. If you followed that pattern your method would be
static List<Student> TypeFilter(this List<Student> result, string type)
{
return result.FindAll(x=>x.type == type);
}
and the usage would be:
List<Student> a = some code;
a = a.TypeFilter("someType");
You could use RemoveAll
:
static void TypeFilter(this List<Student> result, string type)
{
result.RemoveAll(x=>x.type != type);
}
You cant assign it this way try this:
static List<Student> TypeFilter(this List<Student> result, string type)
{
return result.FindAll(x=>x.type == type);
}
Use it like this:
List<Student> a = some code;
List<Student> filteredStudentList = a.TypeFilter("someType");
A is a reference type but a new List was created when FindAll was called. FindAll is a function that returns a new List. It is equivalent to the foolow method:
List<Student> FindAll (List<Student> students, string filter){
List<Student> newList = new List<Student>();
foreach(var student in students){
if(filter == student.type)
newList.Add(student);
}
return newList;
}
If you want to use the return value then you need to capture a reference to the return value by creating a variable:
var filteredStudents = students.TypeFilter("someFilter");
You cannot assign to the this
pointer in a reference method, and any method taking a parameter cannot assign to it without making it a ref
parameter, thus the List
produced by your code can't be assigned to result
the way you've described.
Since it is a List
, you could iterate through and remove items instead of replacing the pointer.
static void TypeFilter(this List<Student> result, string type)
{
foreach(var s in result
.Except(result.FindAll(x => x.type == type))
.ToArray()) // VERY Important - modifying a list while iterating through it will throw an exception!
{ result.remove(s); }
}
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.