meetings/2018/LDM-2018-12-03.md
using declaration open issuesRange indexer on array and FX typesusing declaration open issuesQ: Do we want to reserve '_' to mean discard in a using e.g., using var _ *= ...;?
This would let the user set the scope for an expression without creating an
identifier.
Conclusion
Yes, this seems useful.
Q: Do we want to allow a deconstruction in the declaration e.g., using var (x, y) = GetResources()?
We noted that this could mean two different things: the outer tuple is disposed, then deconstructed, or the elements are deconstructed, then each is disposed.
Conclusion
This seems too complicated for the marginal benefit. Rejected.
goto and using declarationsExample:
goto label;
using var x = ...;
label:
...
Can you goto past a using declaration? Can you goto before a using
declaration? Can you goto in the same block, but not past the using? Can
you even have labels and using var in the same block?
Conclusion
You definitely can't goto "past" a using var. That would be similar to
jumping "into" a try-finally.
We could allow jumping "out" of a using var, but we're concerned it may
be confusing, since there may not be a syntactical indication that the
disposal is executed.
When gotoing a label in the same statement list as a using var, the
goto must not have a using var syntactically between the goto and
the label.
Dispose() and Nullable<T>Q: Should an extension Dispose() method be called if the receiver is null?
No, the behavior is defined as item?.Dispose(), and so Dispose() will not
be called for null values.
Q: For a value of type S? and extension methods Dispose(this S? s) and
Dispose(this S s), which is called?
Same resolution as above: the behavior is defined as value?.Dispose(), so
we do the same thing as item?.Dispose() (which picks Dispose(this S s)).
Proposals:
(3) and (2) are initially attractive because they automatically produce the fastest possible behavior with no allocation. Essentially, users are in a pit of success from a performance perspective.
There are two main problems with this:
string
type.The opposing proposal is (1). The theory is that users are more likely to be able use that they pass in. For many users, the additional allocation and copying will not be prohibitive. For performance sensitive users, instead of passing arrays around directly, they can proactively convert to Span or Memory and all subsequent indexing operations will be 0-allocation.
The main problem with (1) is performance-sensitive users are essentially in a pit of failure in this proposal. The short syntax makes the indexers attractive, but likely to harm performance.
It was also noted that indexers are generally not supposed to hide expensive or complicated operations, according to .NET coding guidelines. However, Range indexers are fundamentally new operations (they even return a different type -- a collection instead of an element) and it's not clear we should naively apply the same standards for existing indexers to Range indexers.
Conclusion
Settled on (1), with overloads for AsSpan(Range r) that return a Span<T>.
This should reduce the work necessary to go directly from a Span-compatible
types to Span slices.
CoreFX Proposal: https://github.com/dotnet/designs/pull/48
Q: Do we want to allow Range/Index indexers on multidimensional arrays? They are currently prohibited.
Conclusion
Undecided. We need to discuss this in another LDM.