1

Since I don't know the term that applies to this, I am not sure what to search for existing comments on this.

I recently wasted a ton of time with an expression body similar to:

public SomeListViewModel SearchSomeModel => new ShowSomeViewModel{...};

When I tried to set values such as:
SearchSomeModel.Property = 12345;

It acted like all was good. But the actual value never changed. When I instead inserted a {get;} as in:

public SomeListViewModel SearchSomeModel {get;} =  new ShowSomeViewModel{...};

It worked correctly.

The funny thing is that if this starts out as a normal get (with a get {return ..} then ReSharper(?) offers to convert it to the first version.

Anyway, I want to understand the difference between the two (no, not at a CLR level) but just to a) know how to refer to each in it's proper terms and b) why one works and the other just pretends to work.

Thanks!

JustMeToo
  • 325
  • 1
  • 14
  • 1
    Simple [TryRoslyn](https://tryroslyn.azurewebsites.net/#b:master/f:r/K4Zwlgdg5gBAygTxAFwKYFsDcBYAUAB2ACMAbMAYxnJIEMQQYBhGAbzxg5kNIpgHsiAK1TlkMAJIBGGAF4AfDAioA7vyEjkACgCUOXJxjtO3MpQHDREgEysYUVMkwwAvrMUq1FrbrzOgA===) that shows the difference... – xanatos Mar 20 '17 at 15:36
  • If I'm not mistaken the expression body evaluates the value always again (i.e. it calls the constructor call you wrote in it every time you read the value from SearchSomeModel), while your second example just initializes a property with the one value, which is then stored and can be modified. – MetaColon Mar 20 '17 at 15:37
  • 3
    Searching the exact title of your question leads to (lots of) pages that explain the answer to your question, so clearly you *did* know of a suitable search term for this problem. – Servy Mar 20 '17 at 15:37
  • @Servy Was that on SO? If so, then this is a dupe, no? – Fildor Mar 20 '17 at 15:38
  • @Fildor The top results were primarily the language documentation (as one would hope to be the case). – Servy Mar 20 '17 at 15:40
  • @Servy - Maybe it was information overload - I found lots of expression body examples, but none of the ones I looked at explained the difference between the 2 forms. – JustMeToo Mar 20 '17 at 16:31

2 Answers2

7

The first line of code -

public SomeListViewModel SearchSomeModel => new ShowSomeViewModel{...};

means that it will create a new instance of ShowSomeViewModel every time that you try to get it.
It is the equivalent of:

public SomeListViewModel SearchSomeModel {
    get {return new ShowSomeViewModel{...};}
}

On the other hand the

public SomeListViewModel SearchSomeModel {get;} =  new ShowSomeViewModel{...};

means you are setting a default value.

Ofir Winegarten
  • 9,215
  • 2
  • 21
  • 27
  • Thank you! This seems fairly clear now that you mention it. Is there a term for either one or at the both just different types of expression bodies? – JustMeToo Mar 20 '17 at 16:28
  • 1
    This is an important distinction. Although it's not a hard rule, it is an expectation that if I "call" `get` a second time without any changes to the object, I will get the same value. It's a "property thing" (aka "mutator" or "accessor"). – Tom Blodget Mar 20 '17 at 16:37
  • @JustMeToo The first as you've mentioned is an expression body property, and the second one i believe can be called a getter only auto-property with an Initializer - that's quite a long term, isn't it? – Ofir Winegarten Mar 20 '17 at 16:44
2

The code

public SomeListViewModel SearchSomeModel {get;} =  new ShowSomeViewModel{...};

gets translated to the equivalent of

private SomeListViewModel _searchSomeModel  =  new ShowSomeViewModel{...};
public SomeListViewModel SearchSomeModel 
{
    get
    {
        return _searchSomeModel;
    }
}

the code

public SomeListViewModel SearchSomeModel => new ShowSomeViewModel{...};

gets translated to the equivlant of

public SomeListViewModel SearchSomeModel 
{
    get
    {
        return new ShowSomeViewModel{...};
    }
}

When using the 2nd form every time you call the property you are getting a new instance of ShowSomeViewModel, when using the first form you get the same object back each call.

The reason the 2nd form did not work was you where updating the value on the old instance but when you called the property a 2nd time to check the value you where getting a new instance of the view model that did not have your changes.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431