代表如何收到其论点?

时间:2011-12-01 23:01:24

标签: c# .net delegates lambda

以下是使用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,但该解析在运行时实际上如何工作?

1 个答案:

答案 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表达式

Lambda表达式是.NET 4的一个非常酷的功能。它们与Lambda函数非常不同,即使语法相同

基本上,当您编写Lambda函数时,它的编译方式与任何其他代码一样。但是,当您编写Lambda表达式时,编译器实际上会生成一组完整描述代码的元数据。通常,代码永远不会实际执行。

这在PropertyChanged事件之类的场景中非常有用,因为此事件需要知道属性的名称,而不仅仅是值。可以分析Lambda表达式,它将指示正在更改的属性是"QuantitySaved"

使用Lambda Expressions可以编写强类型的代码,但允许分析代码而不是执行代码。这是该语言的一个很棒的功能,并支持许多很棒的功能,如LINQ to SQL,但绝对难以理解!