我是一个lambda新手,所以如果我在描述中遗漏了重要信息,请告诉我。我将使示例尽可能简单。
我正在检查别人的代码,他们有一个类继承了另一个类。下面是派生类,以及我理解起来有困难的lambda表达式:
class SampleViewModel : ViewModelBase
{
private ICustomerStorage storage = ModelFactory<ICustomerStorage>.Create();
public ICustomer CurrentCustomer
{
get { return (ICustomer)GetValue(CurrentCustomerProperty); }
set { SetValue(CurrentCustomerProperty, value); }
}
private int quantitySaved;
public int QuantitySaved
{
get { return quantitySaved; }
set
{
if (quantitySaved != value)
{
quantitySaved = value;
NotifyPropertyChanged(p => QuantitySaved); //where does 'p' come from?
}
}
}
public static readonly DependencyProperty CurrentCustomerProperty;
static SampleViewModel()
{
CurrentCustomerProperty = DependencyProperty.Register("CurrentCustomer", typeof(ICustomer),
typeof(SampleViewModel), new UIPropertyMetadata(ModelFactory<ICustomer>.Create()));
}
//more method definitions follow..
注意上面的call to NotifyPropertyChanged(p => QuantitySaved)
位。我不明白"p“是从哪里来的。
下面是基类:
public abstract class ViewModelBase : DependencyObject, INotifyPropertyChanged, IXtremeMvvmViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged<T>(Expression<Func<ViewModelBase, T>> property)
{
MvvmHelper.NotifyPropertyChanged(property, PropertyChanged);
}
}
我敢肯定,这里面有很多与这个问题无关的东西,但我想在包容性方面犯错误。
问题是,我不明白'p‘参数是从哪里来的,也不明白编译器是怎么知道的(显然?)从稀薄的空气中填充ViewModelBase的类型值?
为了好玩,我把代码从'p‘改成了’SampleViewModel‘,因为这是从ViewModelBase继承过来的,但我遇到了一系列的编译器错误,其中第一个错误说明Invalid expression term '=>'
,这让我有点困惑,因为我认为这会起作用。
有人能解释一下这里发生了什么吗?
发布于 2011-12-01 01:52:23
lambda p => QuantitySaved
是一个Expression<Func<ViewModelBase, int>>
类型的表达式。因为方法NotifyPropertyChanged
正在寻找<ViewModelBase, T>
的表达式,所以它是合适的。
因此,编译器能够推断出p
是一个ViewModelBase
。p
不是“来自”任何地方,它基本上就是在这里被声明的。它是lambda的一个参数。当有人使用你的方法的property
参数时,它将被填充。例如,如果您将lambda放入一个名为lambda
的单独变量中,则可以使用lambda(this)
调用它,它将返回QuantitySaved
值。
不能在lambda中使用this
的原因是它需要一个参数名称,而this
不是一个有效的名称。关键是,您可以在ViewModelBase
的任何实例上调用它,而不仅仅是在创建lambda的实例上调用。
发布于 2011-12-01 01:53:15
要理解这一点,最简单的方法是替换它:
p => QuantitySaved // lambda
有了这个:
delegate (ViewModelBase p) { return QuantitySaved; } // anonymous delegate
它们实际上是一样的。p
是匿名委托的第一个参数的参数名。您可以为它指定任何适合参数名称的名称(this
是一个关键字,不能将其用作参数名称)
在这个特殊的例子中,这个p
变量是多余的,顺便说一下,你也可以使用无参数委托。
发布于 2011-12-01 01:46:48
从NotifyPropertyChanged签名:
void NotifyPropertyChanged<T>(Expression<Func<ViewModelBase, T>> property)
该方法需要一个接受ViewModelBase
类型输入的表达式,并返回T
类型的实例。
P参数是ViewModelBase的一个实例。
https://stackoverflow.com/questions/8330446
复制相似问题