1

My question is straightforward. Why this works:

public DelegateCommand LogInCommand { get; }

Func<bool> canExecuteLogIn = () => !StringService.IsNullOrEmpty(_entries.LoginText, _entries.PasswordText);
LogInCommand = new DelegateCommand(OnLogInTapped, canExecuteLogIn);

But this doesn't:

public DelegateCommand LogInCommand => new DelegateCommand(OnLogInTapped,
            () => !StringService.IsNullOrEmpty(_entries.LoginText, _entries.PasswordText));

I check like so:

 public string LoginEntryText
        {
            get { return _entries.LoginText; }
            set
            {
                _entries.LoginText = value;
                LogInCommand?.RaiseCanExecuteChanged();
            }
        }

Doesn't work, I mean that Func never executes after initialization.

Yura Babiy
  • 515
  • 7
  • 22

1 Answers1

1

Question is not entirely clear for me, but I suspect the reason is as follows.

This

public DelegateCommand LogInCommand => new DelegateCommand(...)

Is equivalent to this

public DelegateCommand LogInCommand { get {return new DelegateCommand(...)}}

So every time you access LogInCommand property - it returns new DelegateCommand instance. That means you do RaiseCanExecuteChanged on fresh instance of a command, and all code that called this property before and which can react to this change use their own instances.

That's unlike first scenario where there is just one instance of DelegateCommand used by everyone.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • I thought that expression declaration checks, if an instance was created, internally. But why if I do initialization like you suggested, I have to have fields, that are in use to be static? It means that `=>` and `=` has different initialization mechanism? – Yura Babiy Mar 28 '17 at 10:24
  • Sure `=>` and `=` are different. I've shown in answer what is equivalent of `=>` initialization (for properties, not in general). I didn't understand your first sentence "I have to have fields, that are in use to be static" though. – Evk Mar 28 '17 at 10:27
  • It says me "Cannot access non-static field "_entries" in static context". It also relates to OnLogInTapped. – Yura Babiy Mar 28 '17 at 10:39
  • Ah I missed you access fields in your delegate. Yes then you cannot use that syntax, because it's analog to declaring `readonly` field as a backing field for your property, and you cannot do that in field initializer (see here a little explanation - http://stackoverflow.com/a/7400757/5311735) . So your best bet would be to just use first syntax. – Evk Mar 28 '17 at 10:44
  • It's weird and not clear why `=>` allow to use this fields, and `=` don't. I would like to get a better understanding. But to do it in a constructor is just ok. Thank you for your afforts. – Yura Babiy Mar 28 '17 at 11:11
  • I'll try to explain. As I described, `=>` is complete analog of `{get{return new ...}}`. When getter is executed in this case - instance is already constructed and all fields (such as `_entities`) are initialized. So, constructor has been already run. When you do `{get;} = new ...`, it's analog of declaring a field like this: `_logInCommand = new ...`. When this field initializer is being run - constructor has not been run yet. Your `_entities` field is not initialized yet and so cannot be used (even though you are using it not directly but in delegate). – Evk Mar 28 '17 at 11:15
  • Does properties initialization go after constructor? What I knew, that when I write `{get;} = new`, it executes in constructor anyway. It is just a way of declaring. Does `{get;}=new` is different from just `Property = new Property();` ? (I mean in initialization) – Yura Babiy Mar 28 '17 at 11:20
  • 1
    `Property = new Property()` is not a property - it's a field. `Property {get;} = new ..` is a property backed by readonly field (so: `Property {get {return _property;}} _property = new ...`. Field initializers run _before_ constructor, and so you cannot reference instance members there. I suggest you to read this answer for more clarity: http://stackoverflow.com/a/1920814/5311735. – Evk Mar 28 '17 at 11:23
  • Now I understand. You got my personal respect for your intention to help. – Yura Babiy Mar 28 '17 at 11:36