Open alrz opened 5 years ago
As with how this feature would interact with overload resolution there's some room for tweaks,
void M(List<int> list) {}
void M(IEnumerable<int> list) {}
If new[]
would be convertible to any type just like new()
, both this invocations would be ambiguous,
M(new() { }); // could bind to first method
M(new[] { }); // could bind to second method
While this is good for breaking change predictability, it also means that it's easier to introduce one, and it narrows down where the feature can be used overall.
--
For an untyped new[]
we could only accept arrays AND array generic interfaces as the target type and yield no conversion otherwise. This would be similar to lambas which are only convertible to delegates.
For an untyped new()
we could only accept constructible types or more loosely non-array types instead of any type.
This distinction would eliminate the candidates that are not compatible with the argument from get-go, since we can say if we want to create an array or a non-array type via new[]
or new()
.
Would it not work better to relax the array initializer syntax to allow {{a,b},{c,d}}
instead of {new(a,b),new(c,d)}
for the KeyValuePair example?
I would like if this also included int[] x = new[1];
, not just new[]{...}
.
I think this proposal can effectively be subsumed into collection literals.
You would be able to do the following:
KeyValuePair<string, string>[] array = [new("key1", value1), new("key2", value2)];
That solves the array part. KVP is also very special to collection literals so the above could also be shortened to:
KeyValuePair<string, string>[] array = ["key1": value1, "key2": value2];
Note: A list/dictionary literal feature would not supersede this proposal because in above examples there's no concrete collection type to infer.
We support collection/dictionary literals even the absence of a concrete collection type :)
Right, I think it will also work with IEnumerable but only as long as there is a compatible natural type.
IEnumerable<T> x = [value]; // ok; but the target-type (T) won't affect type inference in any ways here.
IEnumerable<T> x = []; // error; no natural type? (is there a default natural type when the list is empty?)
IEnumerable<bool?> x = [true, null]; // error; the most-common-type is `bool` and `List<bool>` fails to assign.
All of the above would be legal @alrz
Great! Though I didn't find anything about a null-aware common type.. does that last example work with var
?
The last example will work with 'var' if 'best common type' is willing to infer bool?
for true
and null
. So we would be gated on that.
if 'best common type' is willing to infer
bool?
fortrue
andnull
.
Unfortunately, I think it is not. SharpLab
@RikkiGibson right, that's what i'm saying. We're gated on that being a supported concept for c#. the same applies to existing collections today.
When we didn't do that in C# 8, we accepted that it would likely never be done. https://github.com/dotnet/csharplang/issues/881
I opened a discussion thread here: https://github.com/dotnet/csharplang/discussions/7175 But closed it once I found this issue..
In short: It is great if this type of syntax will work in C# 12:
Student[] students = [new("John"),new("Jane")];
But we still should have a goal of implementing this feature on the original syntax for the sake of language consistency.
Student[] studentsB = new[] { new("John"), new("Jane") }; // This would ideally work as well.
Allow
KeyValuePair<string, string>[] array = new[] { new("key1", value1), new("key2", value2) };
With introduction of
new()
expression (#100), the following:can be simplified to:
but you still need to repeat the type following the field/property initializer. Closest you can get is something like:
For the sake of completeness, I'd suggest to also make
new[]
a target-typed expression,The mechanics of such feature is similar to #2389 or #2460 where there are two source of type inference, the common type and the target-type.
Note: A list/dictionary literal feature would not supersede this proposal because in above examples there's no concrete collection type to infer.