-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Labels
Area-CompilersFeature - Default Interface ImplDefault Interface ImplementationDefault Interface ImplementationuntriagedIssues and PRs which have not yet been triaged by a leadIssues and PRs which have not yet been triaged by a lead
Description
interface I1
{
int P1 {get; set;}
int P2 {get => throw null; internal set{}}
int P3 {get => throw null; set{}}
}
class C0 : I1
{
int I1.P1 {get; set;}
}
class C1 : C0, I1
{
public int P1 {get;}
public int P2 {get;}
public int P3 {get;}
}
Observed in IL for C1:
.method public final hidebysig specialname newslot virtual
instance int32 get_P1 () cil managed
.method public hidebysig specialname
instance int32 get_P2 () cil managed
.method public final hidebysig specialname newslot virtual
instance int32 get_P3 () cil managed
Unlike other getters, get_p2 is not marked as final and virtual. This indicates that compiler didn't treat C1.P2 as an interface implementation. This is inconsistent to treatment that C1.P1 and C1.P3 get, which is likely to surprise users.
Also, If I1.P2 didn't have a setter at the beginning, then C1.P2 would be considered to implement it and the getter would have the expected flags. After the internal setter with an implementation is added, the C1.P2 silently isn't considered as an implementation. This effect is likely to be surprising.
If I1.P2 setter is public, C1.P2 is considered as an implementation.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Area-CompilersFeature - Default Interface ImplDefault Interface ImplementationDefault Interface ImplementationuntriagedIssues and PRs which have not yet been triaged by a leadIssues and PRs which have not yet been triaged by a lead