You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Test new betterness rules when two candidates applicable in expanded form and same arguments used in params collection:
(assume T implicitly convertible to TBase)
ReadOnlySpan<T> vs Span<TBase> (ROS is better)
Span/ReadOnlySpan<T> vs TBase[] (Span/ROS is better)
Span/ReadOnlySpan<T> vs IEnumerable<TBase> (Span/ROS is better)
T[] vs IEnumerable<T> (Neither is better)
ICollection<T> vs IEnumerable<TBase> (ICollection<T> is better if covariant conversion exists to IEnumerable<TBase>, otherwise neither is better)
ICollection<T> vs IEnumerable<T> (ICollection<T> is better)
Test usage of all "collection type kinds"
Span<T>
ReadOnlySpan<T>
Create method
Collection initializer.
Require constructor and Add on the type itself (ImplementsIEnumerableT_04_MissingConstructor, ImplementsIEnumerableT_07_MissingAdd)
List interface
Test usage in attribute (invalid) (Span_InAttribute, CreateMethod_02_InAttribute)
Test accessibility of constructor+Add (require at least as 'params' method) (ImplementsIEnumerableT_05_InaccessibleConstructor, ImplementsIEnumerableT_08_InaccessibleAdd)
Test extension Add does not satisfy requirement (ImplementsIEnumerableT_21_AddIsNotAnExtension)
Test when expected members are Obsolete (incl. collection type itself) (incl. suppression thru obsolete context)
Test accessibility of Create method (require at least as 'params' method)
Test dynamic (error when no static resolution and may be applicable in expanded form) (DynamicInvocation_)
Test lambda parameter with params modifier (attribute not emitted) (WRN_ParamsArrayInLambdaOnly_01)
Test local function parameter with params modifier (attribute not emitted) (ParamCollectionInLocalFunctionOnly)
Test better params collection type (BetterConversionFromExpression_)
Test better element type (BetterNess_01_ElementType)
Test different sets of arguments as params arguments (ambiguous) (BetterOverload_02_NotSameCollectionElements)
Ref safety (ParameterRefSafetyScope_)
params is inherited by override but override is not implicitly scoped (ParameterRefSafetyScope_13_Mismatch)
Cannot use params collection in expression tree (ExpressionTree)
Test cycles through expected members, e.g. CollectionType(params CollectionType t). (Cycle_).
Collection type has required member (error at params declaration site) (CollectionWithRequiredMember_)
Type inference (GenericInference) (e.g. void M<T>(params IEnumerable<T> e))
Nullable analysis (NullableAnalysis_)
Disallowed modifier combinations (ref/in/out) (scoped is permitted for ref structs)
params difference between overloads (NoOverloadingOnParams_)
Consuming from metadata, including when metadata has attribute combinations not possible in source (MetadataImport_)
Evaluation order of invocations
Well-known members for using etc. which have params collections
constructor/Add has optional unsafe parameters (overload resolution not affected)
NoPIA (ParamArrayAttribute is transferred when embedding a related API, ParamCollectionAttribute is not)
heads up to F# re: interop
test that VB can consume params collections APIs in normal form
hitting enter at reasonable points within the construct indent properly
params modifier of params collection parameter is carried through when generating an override or interface implementation, similar to params array
analyzer (nice to have) user has M(new List<int> { ... }) but could do M(...)
fixer (nice to have) from void M(params int[] i) which forwards to M((IEnumerable<int>)i) then change to M(params IEnumerable<int> i) and potentially remove void M(params int[] i)
analyzer (nice to have) consider changing from void M(Span<int> s) to void M(params Span<int> s)
The text was updated successfully, but these errors were encountered:
Championed proposal: dotnet/csharplang#7700
Speclet: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/params-collections.md
Feature branch: https://github.com/dotnet/roslyn/tree/features/ParamsCollections
LanguageVersion_01_Declaration
,LanguageVersion_02_CallSite
)ArgumentKind.ParamCollection
#72222IParameterSymbol.IsParamCollection
property #71816ParamCollectionAttribute
once we can test against an SDK with it.T
implicitly convertible toTBase
)ReadOnlySpan<T>
vsSpan<TBase>
(ROS is better)Span
/ReadOnlySpan<T>
vsTBase[]
(Span/ROS is better)Span
/ReadOnlySpan<T>
vsIEnumerable<TBase>
(Span/ROS is better)T[]
vsIEnumerable<T>
(Neither is better)ICollection<T>
vsIEnumerable<TBase>
(ICollection<T>
is better if covariant conversion exists toIEnumerable<TBase>
, otherwise neither is better)ICollection<T>
vsIEnumerable<T>
(ICollection<T>
is better)Span<T>
ReadOnlySpan<T>
ImplementsIEnumerableT_04_MissingConstructor
,ImplementsIEnumerableT_07_MissingAdd
)Span_InAttribute
,CreateMethod_02_InAttribute
)ImplementsIEnumerableT_05_InaccessibleConstructor
,ImplementsIEnumerableT_08_InaccessibleAdd
)ImplementsIEnumerableT_21_AddIsNotAnExtension
)dynamic
(error when no static resolution and may be applicable in expanded form) (DynamicInvocation_
)params
modifier (attribute not emitted) (WRN_ParamsArrayInLambdaOnly_01
)params
modifier (attribute not emitted) (ParamCollectionInLocalFunctionOnly
)BetterConversionFromExpression_
)BetterNess_01_ElementType
)params
arguments (ambiguous) (BetterOverload_02_NotSameCollectionElements
)ParameterRefSafetyScope_
)params
is inherited by override but override is not implicitlyscoped
(ParameterRefSafetyScope_13_Mismatch
)params
collection in expression tree (ExpressionTree
)CollectionType(params CollectionType t)
. (Cycle_
).params
declaration site) (CollectionWithRequiredMember_
)GenericInference
) (e.g.void M<T>(params IEnumerable<T> e)
)NullableAnalysis_
)ref
/in
/out
) (scoped
is permitted for ref structs)params
difference between overloads (NoOverloadingOnParams_
)MetadataImport_
)using
etc. which have params collectionsManual IDE Test Pass
params
classification (shows up as blue)params
completionvoid M(p$$)
,void M($$ IEnumerable<int> e)
params
modifier of params collection parameter is carried through when generating an override or interface implementation, similar to params arrayM(new List<int> { ... })
but could doM(...)
void M(params int[] i)
which forwards toM((IEnumerable<int>)i)
then change toM(params IEnumerable<int> i)
and potentially removevoid M(params int[] i)
void M(Span<int> s)
tovoid M(params Span<int> s)
The text was updated successfully, but these errors were encountered: