-
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
(Proposal) Allow const members for value types using default(...)
#7592
Comments
Maybe the compiler should try emit the code differently for these cases (or IMO all of them). IOW:
|
@leppie How would that work with multiple optional parameters? I.e. something like: public void Foo(Struct1 param1 = Struct1.Value, Struct2 param2 = Struct2.Value)
{
…
}
…
Foo(param1: myValue);
Foo(param2: anotherValue); |
@svick: Good point. |
So what exactly is this proposal? A way to decorate a |
The proposal is for this to be valid, as an example: public class Foo
{
public const CancellationToken None = default(CancellationToken);
public Task FooAsync(CancellationToken cancellationToken = None)
...
} |
👍 |
@jskeet Limited specifically to "aliases" of The original "proposal" isn't really a proposal as it is identifying a potential shortcoming. I'm trying to get specific syntax and behavior that you'd think would solve the shortcoming. So this is really two issues. One would be expanding on what is permitted to be embedded as a Second would be a way to encode that an optional parameter refers to one of these constants. Even if you could define a constant of a specific value (or the default value) it is that value that is embedded as the default value of the parameter, not any reference to the parameter. Otherwise the optional value is ultimately just the value of the constant, not the constant, and callers would still see public class Foo {
public const int None = default(int); // legal
public Task FooAsync(int token = None); // also legal
}
FooAsync(); // intellisense shows default(int), not Foo.None |
@HaloFour: I'm only proposing allowing And yes, it would be good for an optional parameter to encode how its default value was derived (probably via attributes) - although there's accessibility issues there as well (e.g. when generating documentation or using Intellisense, if the caller wouldn't have access to the member in question, then |
@alrz: well you would think that, given that it's your proposal :) But in the same vein, I prefer mine... Names allow semantics to be expressed clearly. |
@alrz: As I've already said, it's too late for
|
While I don't see why |
Why could it not be done? It works for default arguments. Why could the compiler not do the same thing elsewhere? I think I'd like the compiler team to comment on feasibility... But the community is in a good position to discuss desirability. |
I think the proposal actually suggests to make it works for default arguments, meaning that it currently doesn't, right? Or I'm missing something. Anyway, I think this is the reason behind it: // OK, compile-time constant, and you cannot define parameterless ctor for structs
void F(Struct s = new Struct())
// OK, same as above
void F(Struct s = default(Struct))
// Error, Default parameter value for 's' must be a compile-time constant
void F(Struct s = new Struct(1)) Now, imagine this for a // Error, because 'None' could be anything, like 'new Struct()' or 'new Struct(1)'
void F(Struct s = Struct.None) Are you suggesting that |
No, void F(CancellationToken cancellationToken = default(CancellationToken)) This proposal would allow named constants with the value of I'm not proposing that any static readonly field becomes usable as a constant expression - just public struct Foo { ... }
public class Bar
{
public const Foo EmptyFoo = default(Foo);
} Then any time |
@jskeet I was talking about your example in the original post all this time, while you meant something like |
@alrz: Yes, the example in the original post is how nice it could have been if this feature had been introduced from the start. I explicitly specified that it's too late for One wrinkle I hadn't previously considered: we'd need to prohibit the use of user-defined operators for non-built-in types for constants (whereas we need to continue to allow them for |
Issue moved to dotnet/csharplang #336 via ZenHub |
Currently there is a small disparity between optional parameters and
const
declarations. While you can have an optional parameter with a default value ofnew SomeValueType()
ordefault(SomeValueType)
you can't useconst
for non-simple value types. It would be really nice if this were permitted - possibly via some attribute likeconst
declarations fordecimal
values use - to make default arguments more readable. Compare the intent of:and
The latter doesn't compile, because
CancellationToken.None
isn't a constant expression - but it could have been. (We couldn't changeNone
to be aconst
for compatibility reasons, but think of future uses... and a new member could be introduced elsewhere, potentially.)I don't know whether we should also allow a 0-argument constructor call, as is currently allowed for default argument values... I'm leary of that just in case custom parameterless structs (proposed but then dropped for C# 6) are ever introduced. I think we've already got an issue there with default argument values - I wouldn't want to make it worse.
The text was updated successfully, but these errors were encountered: