下面代码如果不使用Lambda表达式,自己写一个函数findobj,你会发现一个问题。
就是if (data.ToString() == "1") return true; 这句是写死的字符串,它应该是个变量。
但是为啥系统的List.Find定义的委托偏偏是下面这样的原型呢?
public delegate bool Predicate<in T>(T obj);
为啥不是下面这样呢?
public delegate bool Predicate<in T>(T obj, T obj2);
System.Predicate<string> find = findobj; var list1 = new List<string>(); list1.Add("1"); list1.Add("2"); list1.Find(find); private bool findobj<T>(T data) { if (data.ToString() == "1") return true; return false; }
下面是使用匿名方法+Lambda表达式,你就发现外部变量可以传入进来了。
变量str是怎么做到传递到匿名函数里去的?
var str = "2";
findobjDelegate find= findobj;
list1.Find(delegate(string s)
{
if (s == str) return true;
return false;
}
);
private bool findobj( string data)
{
if (data == "1") return true;
return false;
}
在这段代码中,str
变量被传递到匿名函数(即闭包)中,这个过程涉及到C#中的闭包和Lambda表达式。
首先,让我们来理解一下闭包。闭包是一个可以访问其外部作用域变量的函数。在C#中,匿名函数(即没有名字的函数)和Lambda表达式都可以被编译成闭包。
在这段代码中,list1.Find
方法接受一个委托(delegate
),这个委托是一个匿名函数。这个匿名函数访问了外部作用域的 str
变量。
当 list1.Find
方法调用这个匿名函数时,它会将列表中的每个元素作为参数传递给这个函数。如果列表中的元素与 str
相等,那么匿名函数将返回 true
,否则返回 false
。
这里的关键是 str
变量被闭包捕获并可以在匿名函数中被访问。即使 list1.Find
方法在匿名函数执行之后结束,str
变量仍然可以在匿名函数中被访问,因为闭包持有对 str
变量的引用。
总结一下,这段代码通过闭包机制将 str
变量传递到匿名函数中,使得匿名函数可以访问并使用 str
变量的值。
因此,对于List.Find方法来它,它那个委托,就是必须使用Lambda表达式来调用,你使用一个委托方法来调用就只能写死判断条件了。
这说明一个问题,.net类库中的一些委托调用,被设计成只能通过匿名函数或者Lambda表达式来调用。设计者也许是故意这样做,好利用闭包来简化调用参数。
勇哥的这个想法,在网上没人聊这个话题,于是问了下AI,
我让AI不使用匿名函数或者是Lambda表示式,写一个调用List.Find()的例子。
结果AI反复写都不对,它只能违规使用匿名函数或者Lambda表达式,才可以完成要求。
最后它这样回答:
AI说的第4点,下面是一个例子:
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { List<string> list = new List<string> { "apple", "banana", "orange", "grape" }; // 定义多播委托 Func<string, bool> multicastDelegate = (string element) => { Console.WriteLine($"Element '{element}' found by the first delegate."); return true; }; // 添加多个委托到多播委托中 multicastDelegate += (string element) => { Console.WriteLine($"Element '{element}' found by the second delegate."); return true; }; // 添加多个委托到多播委托中 multicastDelegate += (string element) => { Console.WriteLine($"Element '{element}' found by the third delegate."); return true; }; // 执行多播委托逻辑 foreach (var element in list) { if (multicastDelegate(element)) { Console.WriteLine("Element found."); } } } }
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!