以下是使用List集合类的示例:
List<int> list = new List<int>();
List<int> evenNumbers = list.FindAll(delegate (int i)
{
return (i % 2) == 0;
});
我经常想知道传递给FindAll()的委托本身是如何为列表中的每个项目回调一次。
这也引出了另一个问题,来自我目前正在处理的一段代码。它使用lambda表达式而不是直接委托:
class SampleViewModel : ViewModelBase
{
private int quantitySaved;
public int QuantitySaved
{
get { return quantitySaved; }
set
{
if (quantitySaved != value)
{
quantitySaved = value;
NotifyPropertyChanged(p => QuantitySaved);
}
}
}
//class continues below....
}
ViewModelBase类看起来像这样(为简洁起见):
public abstract class ViewModelBase : DependencyObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged<T>(Expression<Func<ViewModelBase, T>> property)
{
MvvmHelper.NotifyPropertyChanged(property, PropertyChanged);
}
}
当设置QuantitySaved属性时,SampleViewModel lambda中的'p'会解析为ViewModelBase,但该解析在运行时实际上如何工作?
答案 0 :(得分:1)
这些肯定是两个独立的问题。
委托类型始终指定所有参数和返回类型
FindAll
方法has the following signature:
public List<T> FindAll(Predicate<T> match)
。
Predicate<T>
是代理with the following signature:
public delegate bool Predicate<in T>(T obj)
。
当FindAll
调用谓词时,它必须提供T obj
,如下所示:match(item)
,它将返回bool
。
Lambda表达式是.NET 4的一个非常酷的功能。它们与Lambda函数非常不同,即使语法相同!
基本上,当您编写Lambda函数时,它的编译方式与任何其他代码一样。但是,当您编写Lambda表达式时,编译器实际上会生成一组完整描述代码的元数据。通常,代码永远不会实际执行。
这在PropertyChanged
事件之类的场景中非常有用,因为此事件需要知道属性的名称,而不仅仅是值。可以分析Lambda表达式,它将指示正在更改的属性是"QuantitySaved"
。
使用Lambda Expressions可以编写强类型的代码,但允许分析代码而不是执行代码。这是该语言的一个很棒的功能,并支持许多很棒的功能,如LINQ to SQL,但绝对难以理解!