简体   繁体   English

将扩展方法添加到列表

[英]Add extension method to List

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 ? 列表a没有被过滤,列表应该是引用类型,那么为什么a没有变化,我做错了什么吗?

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. 按defualt传递的参数按值传递。 result is now a local variable that references a list. result现在是引用列表的局部变量。 When you call FindAll - you get back a new reference - the original list that result (and a ) reference is unchanged. 当你打电话FindAll -你得到一个新的参考-原来的列表result (与a )参考不变。

When you reassign the result bask to result , result now references the new object, and the link back to a is broken. 当您将结果重新分配为resultresult现在将引用新对象,并且指向a的链接已断开。 a is unchanged through all of this. a所有这些方面, a都保持不变。

Most Linq methods return a new object instead of modifying the passed in object. 大多数Linq方法返回一个新对象,而不是修改传入的对象。 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 : 您可以使用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. A是引用类型,但是在调用FindAll时创建了一个新的List。 FindAll is a function that returns a new List. FindAll是一个返回新列表的函数。 It is equivalent to the foolow method: 它等效于foolow方法:

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"); varfilteredStudents = 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. 你不能分配给this指针的参考方法,并进行参数的任何方法不能分配给它,而不使其成为一个ref参数,因此List你代码生成不能被分配到result你所描述的方式。

Since it is a List , you could iterate through and remove items instead of replacing the pointer. 由于它是一个List ,因此您可以遍历并删除项目,而不必替换指针。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM