0

I have an interface Service which has a method GoTo

 public interface Service
 {
   bool GoTo(string NextPage , object parameter);
 }

I have a class A as follows

 public class A
 {
    private Service serviceA;

   //constructor of the class
   public A(Service serviceB, ServiceManager serviceManager)
   {
      this.serviceA = serviceB;
   }
   public ObservableCollection<SampleObject> Example { get; } = new 
   ObservableCollection<SampleObject>()
    {
        new SampleObject() { Action=  new DelegateCommand(() => this.serviceA.GoTo("NextPage", null)) 
    },
     
    };

}

I get an error on this saying that the keyword 'this' is not available in the current context. I have looked at A field initializer cannot reference the nonstatic field, method, or property and i can see that the error is due to the variable not being initialized in the constructor but in my case i do that . Any help in understanding this is better would be appreciated?

novice_coder
  • 147
  • 2
  • 10
  • 1
    "but in my case i do that" - no you don't, you initialize the property at the point of its declaration. If you just changed your code to put `Example = new ObservableCollection() { ... }` *in the constructor* it would be fine. – Jon Skeet Sep 09 '20 at 17:40

3 Answers3

5

You're using this in a property initializer. You can't do that. All you've got to do is move the initialization of Example from the point of declaration into the constructor body:

public class A
{
    private Service serviceA;
    public ObservableCollection<SampleObject> Example { get; }

    public A(Service serviceB, ServiceManager serviceManager)
    {
        this.serviceA = serviceB;
        Example = new ObservableCollection<SampleObject>
        {
            new SampleObject
            {
                Action = new DelegateCommand(() => this.serviceA.GoTo("NextPage", null))
            }
        };
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
-1

this in this code new SampleObject() { Action= new DelegateCommand(() => this.serviceA.GoTo("NextPage", null)) is within the scope of SampleObject, not A.

Not the exact answer to your question but using camelCase for private field is a very bad practice, even though it's in the C# standard convention. A widely used convention in the .Net community is to name private field with leading underscore. For example: private Service _serviceA;

This convention helps avoid variable naming conflict like this situation and reduce human mistake on using global variables vs local variables.

TDao
  • 514
  • 4
  • 13
-2

You can solve this problem by declaring a variable (e.g. that) to hold the value of this. For example:

var that = this;

Then replace this with that in your existing code:

that.serviceA.GoTo("NextPage", null)

You would need to replace the property lambda for Example with a proper get block. The first statement of the block should be var code above.

(This is a common technique in JavaScript, not because this is ever "unavailable", but rather because the context of this is not what you want it to be in the place you want to use it. But it can come in handy in C# too occasionally.)

JoelFan
  • 37,465
  • 35
  • 132
  • 205