【问题标题】:pass lambda expression as callback to an extension method and pass parameter to it将 lambda 表达式作为回调传递给扩展方法并将参数传递给它
【发布时间】:2017-07-13 05:18:05
【问题描述】:

我正在尝试理解 lambda 表达式、扩展方法、Linq 和 IEnumerable 接口的概念。你可以猜到我对 c sharp 很陌生。在这里我想出了一个问题,它将包含所有上述概念。这里我有一个包含三个对象的列表。我想更改指定索引中的学生对象的名称属性。我编写了一个接受回调函数的扩展方法。回调函数接受一个整数索引和一个新的名称字符串。它应该更改名称属性并返回对象。但是我的代码未能这样做,因为我不确定如何在扩展方法中将参数传递给 Func 回调。我需要一些助手来理解问题并修复我的错误代码?

class Program
{
    static void Main(string[] args)
    {
        List<Students> students = new List<Students>();

        students.Add(new Students(111443, "sakib"));
        students.Add(new Students(111445, "zami"));
        students.Add(new Students(111444, "habib"));

        var student = students.First();

        var changed1 = students.Change((int num,string newname) => { return students[num].s_name = newname;});


    }
}

public class Students
{
    public int s_id;

    public string s_name;

    public Students(int id, string name)
    {
        this.s_id = id;

        this.s_name = name;
    }
}

public static class LinqHelper
{
    public static IEnumerable<T> Change<T> (this IEnumerable<T> source, Func<int,string,T> callback)
    {
        var myList = new List<Students>();

        myList.Add(callback(1,"zami")); // i was passing parameter here which is not so helpful i guess !

        return myList;

    }
}

【问题讨论】:

    标签: c# asp.net-mvc linq lambda


    【解决方案1】:

    Func 表示一个接受整数和字符串作为输入并接受 T 作为返回类型的函数。您使用的匿名函数的返回类型为“字符串”:

    var changed1 = students.Change((int num,string newname) => { return students[num].s_name = newname;});
    

    您应该从函数中返回学生实例以使其工作。尝试用以下代码替换上面的代码:

    var changed1 = students.Change((int index, string newname) => 
                                             {
                                                 var studentObj = students[index];
                                                 studentObj.s_name = newname;
                                                 return studentObj;
                                             });
    

    要允许 LinqHelper 接受索引和参数,请使用以下命令:

    public static class LinqHelper
    {
        public static IEnumerable<T> Change<T>(this IEnumerable<T> source, Func<int, string, T> callback, int index, string argument)
        {
            var myList = new List<T>();
    
            myList.Add(callback(index, argument)); // i was passing parameter here which is not so helpful i guess !
    
            return myList;
    
        }
    }
    

    然后,您可以按如下方式调用该方法:

    var changed1 = students.Change((int index, string newname) => 
                                             {
                                                 var studentObj = students[index];
                                                 studentObj.s_name = newname;
                                                 return studentObj;
                                             }, 
                                             1, 
                                             "zami");
    

    【讨论】:

      【解决方案2】:

      您尚未创建评估为 Func&lt;int, string, T&gt; 的 lambda。您对更改扩展程序的调用应如下所示:

      var changed1 = students.Change((num, newnam) => {  
                                  students[num].s_name = newnam; 
                                  return students[num];
                               });
      

      (您应该按照Func 的要求返回T)。

      【讨论】:

      • 我已将参数从内部扩展方法传递给回调,例如 myList.Add(callback(1,"zami")) 。但我希望这是动态的。如果我将扩展方法中的参数传递给回调,那么对于每个索引,我必须在扩展方法中进行更改。如何避免这个问题?
      • 您应该将两个新参数添加到您的 Change 方法以传递给回调(例如 Change(1, "zami", () => {...} )(但它会是 '模糊逻辑'IMO。)您还可以创建一个 Func 并传递 lambda: () => { students[1] = "zami"; return students[1]; } - 取决于您想要实现的目标。 ..
      • 谢谢帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多