这在上下文中无效

时间:2013-12-11 13:13:02

标签: c# lambda this

我的问题最初是删除匿名代理。我查看了here找到的答案链。但是我的问题有点不同。由于某种原因,方法Hookup编译。但变量处理程序没有。我得到的错误是“这个”在上下文中无效......但为什么呢?为什么一个方法签名编译但另一个不编译?我可以在这里实现lambda格式吗?我真的想实现lambda格式,因为我相信它更易读,即使它是一个变量。但我真的对此感到好奇,但到目前为止答案都没有。

    protected void Hookup(object sender, PropertyChangedEventArgs args)
    {
        this.OnPropertyChanged(args.PropertyName);
    }

    protected PropertyChangedEventHandler hookup= (sender, arg) => this.OnPropertyChanged(arg.PropertyName);

完整的代码在这里:

public abstract class Notifiable : INotifyPropertyChanged
{
    protected void Hookup(object sender, PropertyChangedEventArgs args)
    {
        this.OnPropertyChanged(args.PropertyName);
    }

    protected PropertyChangedEventHandler hookup = (sender, arg) => this.OnPropertyChanged(arg.PropertyName);

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged == null) return;
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    protected void OnObservableChanges(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
            foreach (var item in e.NewItems)
                (item as INotifyPropertyChanged).PropertyChanged += this.Hookup;//(osender, arg) => this.OnPropertyChanged(arg.PropertyName);
        if (e.OldItems != null)
            foreach (var item in e.OldItems)
                //This is the real reason for my problem. I need to be able to unhook the commented out anonymous call. 
                //As you can see, the lambda format is much easier to read and get the gist of what's up.
                (item as INotifyPropertyChanged).PropertyChanged -= this.Hookup;//(osender, arg) => this.OnPropertyChanged(arg.PropertyName);
    }
}

1 个答案:

答案 0 :(得分:3)

因为您在此处对实例字段使用变量初始值设定项:

protected PropertyChangedEventHandler hookup= (sender, arg) => this.OnPropertyChanged(arg.PropertyName);

但是你不允许这样做。

来自C# specification

  

10.5.5.2 10.5.5.2实例字段初始化
  ...
  实例字段的变量初始值设定项无法引用正在创建的实例。因此,在变量初始化程序中引用this是编译时错误,因为变量初始化程序通过简单名称引用任何实例成员是编译时错误。


但是,您可以在构造函数中初始化hookup

public abstract class Notifiable : INotifyPropertyChanged
{
    protected PropertyChangedEventHandler hookup;

    public Notifiable()
    {
        hookup = (sender, arg) => OnPropertyChanged(arg.PropertyName);
    }

    ...
}