Refactorings for clarity
This commit is contained in:
Родитель
979330b632
Коммит
d16fdec5b4
|
@ -16,21 +16,21 @@ People will be able to write better code by hand than the compiler can generate
|
|||
|
||||
When an exact count is known for a collection literal but the compiler can't prove that it is not potentially resized later, or when only a minimum count is known for a collection literal, the compiler could for example set the initial capacity to the best-fitting power of two. This would skip some early resizes while also amortizing resizes that could happen if the collection is modified after the collection literal is created.
|
||||
|
||||
### Unknown-length construction
|
||||
### AddRange and boxing
|
||||
|
||||
When a struct-typed collection is spread, codegen could call `AddRange(IEnumerable<T>)` on the collection being constructed. This would cause the collection being spread to be boxed. To avoid boxing, codegen could loop over the spread collection and call `Add(T)` repeatedly on the collection being constructed.
|
||||
|
||||
This would work fine when the constructed collection has a writeable Capacity property because codegen could set the capacity before calling `Add(T)` in a loop. However, if there's no writeable Capacity property, we're better off calling `AddRange` and boxing, because the `AddRange` implementation is the only way to intelligently avoid intermediate resizes. (In this situation, the thing being spread has a known length but the collection literal as a whole has an unknown length due to an earlier spread.)
|
||||
|
||||
#### Conclusion (unknown-length construction)
|
||||
#### Conclusion (AddRange and boxing)
|
||||
|
||||
Stick with building using Add and AddRange. This is good enough for 95% of customers. Allow the compiler to special-case codegen for widely-used collections to improve performance.
|
||||
|
||||
The compiler should prefer calling `AddRange(ReadOnlySpan<T>)` if such a method exists and the thing being spread is a span or exposes a span.
|
||||
|
||||
### Known-length construction
|
||||
### Construction API pattern
|
||||
|
||||
The ideal API for constructing collections with contiguous backing storage is to pass the capacity and receive a span to the backing storage. To enable creation methods to be in the same class while having the same name, the collection could be passed back using an `out` parameter.
|
||||
The ideal API for constructing collections with contiguous backing storage is to pass the capacity and receive a span to the backing storage. The collection could be passed back using an `out` parameter to enable overloading on collection type.
|
||||
|
||||
The type parameter to use when calling the creation method could be taken from the generic type argument of the collection's `IEnumerable<>` implementation. This strategy would not work for collections which implement `IEnumerable<>` more than once.
|
||||
|
||||
|
@ -70,7 +70,7 @@ public static class MyCollection
|
|||
}
|
||||
```
|
||||
|
||||
#### Conclusion (known-length construction)
|
||||
#### Conclusion (construction API pattern)
|
||||
|
||||
Use an attribute to point to a creation method similar to the code samples above. If this attribute is present, prefer it over generating Add/AddRange calls.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче