-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Labels
Area-CompilersFeature - Extension EverythingThe extension everything featureThe extension everything feature
Milestone
Description
Spec for methods/properties: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/extensions.md
Spec for operators: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/extension-operators.md
Championed issue: dotnet/csharplang#8697
- Signature conflict in context of extension type (the outer static class)
- Might add more coverage for indexers and properties for completeness sake
- ctrl-F for
https://github.com/dotnet/roslyn/issues/76130in source before done as we converted PROTOTYPE comments to reference this when we merged tomain.
Core feature
- Language version
- Parsing
-
extensionkeyword - Type parameters
- Parameter list
- Empty
- One parameter
- More than one parameter
- Parameter name can be omitted
- The receiver parameter is not allowed to have modifiers if it is unnamed
- Named receiver parameter is only allowed to have the refness modifiers and
scoped.
- Constraints
- Body
-
; - Empty
- Extension member declarations are syntactically identical to corresponding instance and static members in class and struct declarations
- Constructor declarations
- Method declarations
- Property declarations
- Operator declarations
- Event declarations
- Type declarations
-
-
- Static classes as extension containers
- Extension declaration must be in a top level non-generic static class
- Can co-exist with other type members
- Scope of names
- Type parameters are in scope within the body of the extension declaration.
- Receiver parameter is in scope within the body of the extension declaration.
- It is an error to refer to the receiver parameter from within a static member, except within a
nameofexpression. - It is an error for members to declare type parameters or parameters (as well as local variables and local functions directly within the member body) with the same name as a type parameter or receiver parameter of the extension declaration.
- It is not an error for the members themselves to have the same name as the type parameters or receiver parameter of the enclosing extension declaration
- Lookup
- Member names are not directly found in a simple name lookup from within the extension declaration
- Members of the enclosing type and namespace can be found in a simple name lookup
- Extension type parameters and extension parameter are found first
- Extension members
- Instance members are disallowed if the enclosing extension declaration does not specify a receiver parameter name
- It is an error to specify the following modifiers:
abstract,virtual,override,new,sealed,partial, andprotected(and related accessibility modifiers). - Properties may not have
initaccessors. - Cannot have name of the static enclosing class
- Cannot have name of the extended type
- It is an error to decorate an extension member with the [ModuleInitializer] attribute.
- Within a given enclosing static class, the set of extension member declarations with the same receiver type (modulo identity conversion and type parameter name substitution) are treated as a single declaration space similar to the members within a class or struct declaration, and are subject to the same rules about uniqueness.
- OverloadResolutionPriorityAttribute is allowed. The enclosing static class is considered the "containing type" which rules consider.
- Any OverloadResolutionPriorityAttribute attribute present on an extension property is copied onto the implementation methods for the property's accessors, so that the prioritization is respected when those accessors are used via disambiguation syntax.
- Methods of extension blocks do not qualify as entry point candidates
- Receiver parameter
- Receiver parameter can specify
ref,ref readonlyandinmodifiers, as long as the receiver type is known to be a value type. - Not implemented and not tested: If ref is specified, an instance member or one of its accessors can be declared
readonly, which prevents it from mutating the receiver - If the receiver parameter is named, the receiver type may not be static.
- The receiver parameter bears the same restrictions as the first parameter of a classic extension method.
- The [EnumeratorCancellation] attribute is ignored if it is placed on the receiver parameter.
- Receiver parameter can specify
- Implementation methods
- Implicitly declared within enclosing static class
- They are static
- Other modifiers inherited
- Name inherited
- Type parameters inherited
- Parameters inherited
-
thismodifier
-
- Can be consumed by a user directly
- "Participate" in the member uniqueness rule for the enclosing static class
- Entry point candidates.
- IL generation
- Lambdas
- Local functions
- Delegate caching
- Dynamic call sites
- Instrumentation
- Consumption of extension members
- Accessibility
- Member lookup includes all extension declarations within static classes that are using-imported
- Only as part of resolution are candidates with incompatible receiver types discarded.
- A full generic type inference is attempted between the type of the arguments (including the actual receiver) and any type parameters (combining those in the extension declaration and in the extension member declaration).
- When explicit type arguments are provided, they are used to substitute the type parameters of the extension declaration and the extension member declaration.
- Overload resolution
- Ref safety analysis
- Participation in various pattern-based scenarios (foreach, deconstruction, etc.)
- Scenarios for expression tree generation involving extension members
- Ambiguity scenarios
- Delegate creation
- Used usings
- Nullability analysis
- String interpolation related attributes
- Metadata
- Grouping types
- Grouping type members
- Marker types
- Marker methods
- ExtensionMarkerName attribute
- Application
- Synthesize if not defined
- Exported types
- Forwarded Types
- Grouping types
- XML doc comments
- On extension block
- Merged per marker type
- On extension member
- On implementation member
-
crefreferences to members
- On extension block
- Analyzer Actions for extension block and members.
- SemanticModel APIs
- Lookup related as well
- Symbol display
- Public API
- Consumption scenarios from VB
Operators
-
LangVer
-
check parameter and return types
-
null-coalescing assignment
-
cref
-
Completeness
- Address another set of functionality gaps for extension operators #79227 - unsafe modifier
- partial modifier
- Nullability suppression
- Nullable analysis with interesting target-typed expressions as operands (null, lambda, collection expression)
- Cover null-conditional compound assignment (including nullable analysis)?
- Address some known functionality gaps for extension operators #79167 - Cover usage scenarios during tuple comparison (==/!=). There is a relevant comment in
Binder.BindTupleBinaryOperatorInfo. The assumption is things just work.
Productivity
Partners
- BCL tools APICompat, GenAPI, and ApiDiff need support for extension everything sdk#48983
- Add
ExtensionMarkerNameAttributeto BCL (Add ExtensionMarkerAttribute runtime#118188) - ping metadata consumers (SandCastle)
Follow-up/tracking issues:
- diagnostic quality
- public APIs
- known functionality gaps
- nullability
using directives follow-ups- metadata follow-ups
- EnC support
- interpolated strings follow-ups
- consider adjusting receiver requirements
- optimization and code quality
- parsing
- cref follow-up
indexersadjust resolution on type receiverExtensions: Ignore ref kind of extension parameter for static members in betterness #79885remaining pattern-based scenarios: collection expressionsExtensions: Address follow-ups related to collection expressions #79877instrumentationExtensions: address instrumentation follow-ups #79557adjust conflict rules
Cut list
- indexers
- readonly members (discussion)
- conflict between extension parameter name and parameter name on a static extension member
- EnC support (we'll block edits for .NET 10)
- allow
partialmembers - considering some top-level syntax (potentially to alleviate factory scenarios)
- various parsing errors
- language design:
- access on generic type parameter: Generic static extension member errs when used on a type parameter csharplang#9651
- disambiguation between extension method and property, or betterness before determining member kind: Extensions: Extension method prevents extension property of the same name from being accessed csharplang#9653
- two phase or partial type inference
- CREF to extension block
- nameof to extension property: `nameof` doesn't work with extension properties csharplang#9655
Sub-issues
Metadata
Metadata
Assignees
Labels
Area-CompilersFeature - Extension EverythingThe extension everything featureThe extension everything feature