5.1 KiB
C# Language Design Notes for March 4th, 2019
Agenda
- Nullable user studies
- Interpolated string and string.Format optimizations
Discussion
The 'default loophole'
var y = default(SomeStructWithNonNullableFields);
For the above, no warning is produced. The same is true for other default
expressions. Is that OK?
Conclusion
Let's continue to track the nullability of the fields and not produce a warning. If we were to produce a warning it seems likely that we would produce warnings that are fundamentally unactionable because the user doesn't control the struct definition.
User study for nullable design
Today we went over the results from some user studies which simulated upgrading a code base with the non-nullable reference types design enabled.
There were 5 sessions, with two simple, but non-trivial, code bases:
- Telegram bot API
- Jil, a JSON serializer
Problems:
-
People had a fair amount of problems with member definitions, rather than bodies
-
We haven't published much information on how nullable interacts with definitions
-
Interface implementation and overriding are hard to fix since there are multiple places that need to change for every nullability change
-
-
Object initializer pattern is a persistent problem and the warnings don't seem to be providing much value
-
Constructor chaining is also a problem, where fields are piecewise initialized
-
Worse, when looking at the diagnostic, it was hard to get to the member, but when you're at the member, it's hard to verify this one was the problem because the diagnostic also does not occur
-
Almost everyone expected the warnings to be on the field/property
-
-
Nullable value types are a problem because they assumed that the problems were in nullable reference types, but the problems/solutions were subtly different
-
Diagnostic quality: generics were confusing, especially with tuples
-
Code fixes
-
People definitely want code fix to/from a nullable reference
-
They want a "fix-all" but it's not clear what that is
- Some people wanted to see all the warnings, but then narrow down, especially via a code fix
-
-
Some people looked at the process as "satisfying the compiler" and others looking at "code hygiene" or "possible bugs"
-
There were at least a few null-safety bugs and no one found them in the time allotted, but probably would have
-
People who used the feature for overall code hygiene were more excited about using the feature
-
params
and string interpolation
We discussed a new proposal for improving the performance of certain string.Format calls and interpolated string expressions.
Proposal: https://github.com/dotnet/csharplang/blob/master/proposals/format.md
Summary:
Using certain APIs, especially params
and string.Format
, can be a source
of large performance problems. For certain projects (MSBuild) that are
"string manipulation" programs, this can even be the main performance
bottleneck for those programs.
Unfortunately, these APIs are also very convenient and, in many cases, the preferred way of accessing certain string manipulation functionality in the .NET framework. We'd like it if these features could be less heavyweight.
Proposals:
- Allow
params
to have any of the typesSpan<T>/ReadOnlySpan<T>/IEnumerable<T>
Advantages:
-
The callee cannot stash the parameter, so we can re-use an allocation
- Sometimes users do this themselves because it's demonstrably more efficient
Consequences:
Overload resolution needs to change. New tie breaking rules:
-
ReadOnlySpan<T>
-
Span<T>
-
T[]
-
IEnumerable<T>
- Allow any standard
Format
overload resolution for interpolated strings
This feature builds on (1). If interpolated strings could use new Format
overloads that have ReadOnlySpan<T>
arguments, interpolated strings could
share in the performance improvements.
ValueFormattableString
Support new ValueFormattableString
type as a target of a string
interpolation.
This would be a breaking change when people upgrade to the new framework with
the new type, but the older compiler always chooses the string
overload (because
it doesn't understand ValueFormattableString
) and whenever they upgrade the
compiler the call suddenly changes to ValueFormattableString
. If those two
methods do anything different, that would be a breaking change.
This feature also does not support using a custom type instead of
ValueFormattableString
. That could be desirable for a number of different
scenarios, but would probably make the backwards compatibility constraints
even more difficult.
We should carefully evaluate the tradeoffs in this feature and see what we can do to enable the most scenarios without taking unacceptable breaks.
stackalloc
theSpan
forparams
It's not possible for C# to generally predict whether or not it's OK to stackalloc arguments. We're interested in enabling this functionality if provided with a "maybe stackalloc" helper from the runtime, and we'd like to keep that possibility open, but we will not do anything here until such a feature is available.