1

My problem was originally to remove an anonymous delegate. I have looked at the chain of answers found here. However my question is a bit different. For some reason the method Hookup compiles. But the variable handler does not. The error I get is that "this" is not valid in the context... but why? Why does one method signature compile but the other does not? Can I achieve lambda format here? I would really like to achieve the lambda format because I believe it is more readable even if it is a variable. But really I am curious about this, but so far the answer eludes me.

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

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

The full code is here:

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);
    }
}
Community
  • 1
  • 1
Price Jones
  • 1,948
  • 1
  • 24
  • 40

1 Answers1

3

Because you use a variable initializer for an instance field here:

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

But you're not allowed to do that.

From the C# specification:

10.5.5.2 10.5.5.2 Instance field initialization
...
A variable initializer for an instance field cannot reference the instance being created. Thus, it is a compile-time error to reference this in a variable initializer, as it is a compile-time error for a variable initializer to reference any instance member through a simple-name.


However, you can initialize hookup in the constructor:

public abstract class Notifiable : INotifyPropertyChanged
{
    protected PropertyChangedEventHandler hookup;

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

    ...
}
sloth
  • 99,095
  • 21
  • 171
  • 219