Proposal: Using non compile-time constants as optional parameter values #1702
Replies: 13 comments
-
The problem I see with this idea is one of discoverability. If I have a method: void UpdateDateOfBirth(DateTime newDateOfBirth, Person person = null)
{
... Intellisense will show me that What you are proposing is to have the compiler lower: void UpdateDateOfBirth(DateTime newDateOfBirth, Person person = new Person(""))
{
... to: void UpdateDateOfBirth(DateTime newDateOfBirth, Person person = null)
{
person = person ?? new Person("");
... So the signature hasn't changed. As a consumer of your API, I'm gaining no benefit from this feature. I still have to examine the method body to understand what happens in the case of |
Beta Was this translation helpful? Give feedback.
-
Fair point, but in C# 8.0 nullable refence types probably will be implemented, so the current syntax wouldn't really work anymore if I'm correct: void UpdateDateOfBirth(DateTime newDateOfBirth, Person person = null) // Warning: Person can't be null
{
person = person ?? new Person("");
... So the solution would be following (by declaring the parameter as nullable): void UpdateDateOfBirth(DateTime newDateOfBirth, Person? person = null)
{
person = person ?? new Person("");
... So every method and constructor will still have all optional parameters as necessarily nullable... |
Beta Was this translation helpful? Give feedback.
-
Related: dotnet/roslyn#5474 I would prefer the CLR provide this capability without a need for lowering, but I seriously doubt this meets the standard for breaking forward compatibility. |
Beta Was this translation helpful? Give feedback.
-
Perhaps an indicator attribute can be inserted so that future compilers (including other languages) can pick up on it. |
Beta Was this translation helpful? Give feedback.
-
Wouldn't you know that the compiler already has such an attribute, but that it only works for public static void Main(String[] args) {
Test();
}
static void Test(decimal d = 1.0m)
{
Console.WriteLine(d);
} gets emitted as: using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
public static void Main(String[] args) {
var d = new decimal(1, 0, 0, 0, 10);
Test(d);
}
static void Test([Optional, DecimalConstant(1, 0, 0, 0, 10)] decimal d)
{
Console.WriteLine(d);
} |
Beta Was this translation helpful? Give feedback.
-
The framework also declares an abstract attribute, |
Beta Was this translation helpful? Give feedback.
-
And VB.NET adds another for I'm not sure how practical it would be to make this general purpose, though. And the scenarios listed in the original post seem to indicate invoking some code vs. some kind of serializable value. |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
I vote that above comment be deleted for being off-topic, non-constructive and combative. |
Beta Was this translation helpful? Give feedback.
-
We no longer delete comments but mark them appropriately. This allows us and the community to keep a record of problematic content. |
Beta Was this translation helpful? Give feedback.
-
Good idea, otherwise it would look like I was trying to report myself. 😄 |
Beta Was this translation helpful? Give feedback.
-
You're not. All it is is a warning, nothing more. The code will still work fine. |
Beta Was this translation helpful? Give feedback.
-
Slightly different proposal, but often we have method overloads like (especially constructors): class MyClass
{
public MyClass()
: this(int.MaxValue)
{
}
public MyClass(int integer)
: this(integer, TimeSpan.Zero)
{
}
public MyClass(int integer, TimeSpan time)
: this(time, integer, DateTime.Now)
{
}
public MyClass(TimeSpan time)
: this(time, int.MaxValue, DateTime.Now)
{
}
public MyClass(TimeSpan time, int integer, DateTime date)
{
}
} The idea would be to allow the developer to just write: class MyClass
{
public MyClass(TimeSpan time = TimeSpan.Zero, DateTime date = DateTime.Now, int integer = int.MaxValue)
{
}
} with the constraint that non-compile-time constants must appear before compile-time constants. class MyClass
{
[Generated] // or some other attributes to help the analyser identify the candidates
public MyClass(TimeSpan time, int integer = int.MaxValue)
: this (time, DateTime.Now, integer)
{
}
[Generated]
public MyClass(DateTime date, int integer = int.MaxValue)
: this (TimeSpan.Zero, date, integer)
{
}
[Generated]
public MyClass(TimeSpan time, DateTime date, int integer = int.MaxValue)
{
}
} Of course the main inconvenient is the explosion of generated code. But I could see great benefit, since those "magic values" can now be more easily documented. And while they won't be visible in metadata (maybe as verbatim string representing the code??) a smart code analyser can still display them in an IDE. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
For example:
What if we could write:
and the rest would be generated.
Beta Was this translation helpful? Give feedback.
All reactions