-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Language feature: Static Expressions #10506
Comments
Seems very related to the half-dozen or so lazy/cached initialization proposals already made: #3630, #524, #3251, #4374, #3415. What exactly are the semantics? I assume that the result of the expression is promoted to a field, but is that a I will note that while VB.NET uses the |
Wow, it's indeed half a dozen :) The first two are for fields only. The 3rd is for a synchronized lazy expression which I am not proposing. Number 4 is kind of unrelated. Number 5 is for lazy fields. I propose semantics exactly identical to a |
You can't use method type parameters. |
@alrz good catch! Maybe we can fix this if the compiler generates a hidden static class that has type arguments. I think it should do that anyway so that the This would also work in the following case:
Because the generated class can use the manually defined statics from the outer class. Statics introduced by |
Open questions:
|
@GSPP VB doesn't allow this ( Anyhow, considering that static fields would never GC'd I think this encourages to making a lot of things wrapped in |
Understandable. My counter argument to that is that fields tend to be placed at unrelated points in the source code. Many code styles demand ordering members by type. I personally don't view this as a useful organization scheme. It is rare that someone needs to see all fields or all methods in one place. It is more common to want to see everything related to one feature. So I like to place all members of one feature together. So far the tooling is always working against me with that. |
That's true for properties' backing fields, but static fields have a one-to-one relationship with the type itself so it would make more sense to declare static fields (at least) at the top regardless of where they are actually being used. |
I'd rather do #10552. |
I don't think that |
@GSPP Just to play devil's advocate, you can currently write static Func<string, bool> IsMatch { get; } = GetEmailRegex().IsMatch; From my point of view, the problem with using |
@aluanhaddad all semantics are exactly identical to a static field declared in the enclosing type. From that all answers follow: One value per generic instantiation and the value is shared across instances. I find these semantics super easy to understand. |
@GSPP you answered my question which was whether or not instances shared the static value. A lot of use cases for cached properties involve having one cached value per instance. Would there be no way with this proposal to have an instance property or method backed by a per instance cached field? If that were allowed, the |
@aluanhaddad there is no proposal for cached instance state by me. This seems hard to get right. I believe there are multiple other tickets about that, see #10506 (comment). |
@GSSP Roger, static expression apply to static members only. |
We are now taking language feature discussion in other repositories:
Features that are under active design or development, or which are "championed" by someone on the language design team, have already been moved either as issues or as checked-in design documents. For example, the proposal in this repo "Proposal: Partial interface implementation a.k.a. Traits" (issue 16139 and a few other issues that request the same thing) are now tracked by the language team at issue 52 in https://github.com/dotnet/csharplang/issues, and there is a draft spec at https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md and further discussion at issue 288 in https://github.com/dotnet/csharplang/issues. Prototyping of the compiler portion of language features is still tracked here; see, for example, https://github.com/dotnet/roslyn/tree/features/DefaultInterfaceImplementation and issue 17952. In order to facilitate that transition, we have started closing language design discussions from the roslyn repo with a note briefly explaining why. When we are aware of an existing discussion for the feature already in the new repo, we are adding a link to that. But we're not adding new issues to the new repos for existing discussions in this repo that the language design team does not currently envision taking on. Our intent is to eventually close the language design issues in the Roslyn repo and encourage discussion in one of the new repos instead. Our intent is not to shut down discussion on language design - you can still continue discussion on the closed issues if you want - but rather we would like to encourage people to move discussion to where we are more likely to be paying attention (the new repo), or to abandon discussions that are no longer of interest to you. If you happen to notice that one of the closed issues has a relevant issue in the new repo, and we have not added a link to the new issue, we would appreciate you providing a link from the old to the new discussion. That way people who are still interested in the discussion can start paying attention to the new issue. Also, we'd welcome any ideas you might have on how we could better manage the transition. Comments and discussion about closing and/or moving issues should be directed to #18002. Comments and discussion about this issue can take place here or on an issue in the relevant repo. I am not moving this particular issue because I don't have confidence that the LDM would likely consider doing this. |
Sometimes, you want to compute a value once and cache it for the rest of the application's lifetime. Common cases are:
Regex
instancesDictionary
andHashtable
MemoryStream
Currently, you'd do this:
This code is not ideal because although the variable and the function are directly related they often end up being physically at separate places in the source.
This would be more convenient:
And
static(expression)
would automatically convert that expression into astatic readonly
variable.An alternative feature would be to allow placing the
static
variable into a method. This would not change anything about semantics but would allow developers to group their code better. The variable travels with the code that uses it. C++ has this feature.I often find myself thinking "This expression is a constant. I could cache it but I won't bother creating the variable and causing more work for myself in the future. I'll just new up that object constantly to have an easier time programming.".
Collection of cases:
The text was updated successfully, but these errors were encountered: