Proposal: Automatic getter-properties with expression bodies should get some syntax for caching. #1045
Replies: 15 comments
-
problem with your syntax is here is alternative way.
|
Beta Was this translation helpful? Give feedback.
-
This is similar to proposals #133 and #140.
This isn't obvious from the syntax. I think it would be confusing to have completely different behavior between these scenarios: int Prop1 => value = CalculateProperty(); // Cached
int Prop2 => val = CalculateProperty(); // Evaluated every time |
Beta Was this translation helpful? Give feedback.
-
There are a couple proposals on this already, but in the meantime does |
Beta Was this translation helpful? Give feedback.
-
class MyLazyClass
{
int Prop1 => lazy CalculateProperty();
} |
Beta Was this translation helpful? Give feedback.
-
@VanKrock ok if you want keyword just go ahead
|
Beta Was this translation helpful? Give feedback.
-
#312 and #681 have discussed this extensively already. In particular, I find this to be the neatest solution so far: #681 (comment) |
Beta Was this translation helpful? Give feedback.
-
the idea is to reduce the number or artifacts in the source file that has to be written to implement a cached property to one, ideally without having to write too much noise, and without the client of the class needing to know that the property is cached. @MkazemAkhgary and @bondsbw : I thought of the value keyword because it is used in setters, so developers are familiar with it, and - just like in setters - it shadows existing members named value, making them inaccessible in the setter right now, so using it in the getter, too doesn't seem to be a problem. if you want to protect the case where there are existing getters that do access a field or property named value, some opt-in setting combined with an analyzer could work. |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h LazyInitializer.EnsureInitialized not only requires an explicit backing field declaration but also (if null is allowed or we have a value type) to even a third field to remember the initialization. I initially played around with a caching class that led to a syntax like this: // corrected typo. thanks @VanKrock |
Beta Was this translation helpful? Give feedback.
-
@AdmiralSnyder "third field"? You could try |
Beta Was this translation helpful? Give feedback.
-
public string Prop1 => Cache.Lookup(this, Calculate()/, "Prop1" provided by CallerNameAttribute/); Calculate() called for every call Prop1. Use Func: () => Calculate(); public string Prop1 => Cache.Lookup(this, () => Calculate()/, "Prop1" provided by CallerNameAttribute/); |
Beta Was this translation helpful? Give feedback.
-
@MkazemAkhgary |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h this seems to be exactly what i need for the Cache class. Didn't know about that. thanks so much. |
Beta Was this translation helpful? Give feedback.
-
@VanKrock lazy is not part of the signature, any way having keyword for such unique use case seems overkill. There are already good solutions provided. no need for new keyword. |
Beta Was this translation helpful? Give feedback.
-
i got it down to |
Beta Was this translation helpful? Give feedback.
-
Using a backing field without naming it was considered in https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-04-01.md |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Problem
when implementing a property that should get cached using an expression body, you need to produce a redundant backing field:
the Lazy class helps here:
but this is not useful if CalculateProperty() isn't static. you cannot access instance members in initialization code. So either we are back to:
... which makes the notion of a lazy redundant, or putting the instanciation of the lazy into the constructor, which destroys locality, and makes it neccessary to have a third place and second time that we have to do initialization for our property.
My suggestion
Add a context-specific keyword "value" to the property getter expression:
a getter expression that's an assignment to value will only be fetched once, because the fact that the initalization has occured is remembered; value could be backed by an implicit lazy backing field.
Beta Was this translation helpful? Give feedback.
All reactions