Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Proposal: Adjust Member Resolution Algorithm Priority Based on if the Receiver Is Static or an Instance#9525

Unanswered
LeQuackers asked this question inLanguage Ideas
Discussion options

The Problem

A while ago I was playing around with the new C# 14 property extensions and ran into#9517. At glance it looks like a bug, but upon closer inspection it's actually caused by the current member resolution algorithm (seedotnet/roslyn#79309 (comment)).

Example of Problem Using C# 14 Extensions:
varx=newC().M;// CS8917: The delegate type could not be inferredSystem.Console.Write(x);publicstaticclassExtensions{extension(Cc){publicintM=> C.M();}}publicclassC{publicstaticintM()=>thrownull;}
Non-Extension Example of Problem:
varx=newC().M;// CS8917: The delegate type could not be inferredSystem.Console.Write(x);publicclassBase{// Note: the property is defined in Base so that it comes after the static method, in a similar way that extension members come after non-extension memberspublicintM=>42;}publicclassC:Base{publicstaticintM()=>thrownull;}

Essentially, the member resolution algorithm is finding the static method first because extensions are prioritized last. Checking for extensions last makes sense; however, in practice resolving to thestatic member first instead of theinstance member on an instance isn't intuitive:

  • If the receiver is an instance, why does the compiler prioritize the static member when there's a valid instance member of the same name?
  • If the receiver is an instance, why does the compiler prioritize the static member that would cause a CS8917 (orCS0176 if I tried to invoke it) error?
  • If the receiver is an instance, shouldn't the compiler know that I'm trying to use an instance member?

Proposed Solution

Prioritize members based on if the receiver is static or an instance, i.e.:

  • If the receiver is an instance, then perform the current member resolution algorithm with only instance members. If no applicable instance members are found, then perform it with static members.
  • If the receiver is static, then perform the current member resolution algorithm with only static members. If no applicable static members are found, then perform it with instance members.
Example:
/* Because the receiver is an instance, instance members are prioritized first: * 1. instance `C4.M` * 2. instance `C2.M` * 3. static `C5.M()` * 4. static `C3.M()` * 5. static `C1.M()` */varx=newC5().M;System.Console.Write(x);// Prints "4"publicclassC1{publicstaticintM()=>1;}publicclassC2:C1{publicintM=>2;}publicclassC3:C2{publicstaticintM()=>3;}publicclassC4:C3{publicintM=>4;}publicclassC5:C4{publicstaticintM()=>5;}

Current Risk

At the moment, if you use C# 14 extensions to add a property to a 3rd party type, there's a risk that your code will break if said 3rd party adds a method of the same name to that type in the future (i.e. minor version updates have the potential to break your code now), which can lock you into deprecated package versions if you're not careful. An example being abool IsAscii { get; } instance extension property onchar, which would work fine in .NET 4.8 and .NET Standard 2.0, but fails in .NET Core because thechar.IsAscii(char) static method exists in later versions.

Note that the current purposed solution only mitigates the risk by preventing instance members and static members from interfering with each other; if you have an instance extension property on a 3rd party type and they add an instance method of the same name later on, your code will still break.

Drawbacks

I haven't looked at the member resolution algorithm in-depth yet, but stable-sorting instance/static members to the front or needing to perform the member resolution algorithm twice would add overhead.

Breaking Changes

The proposed solution alters the member resolution algorithm, so I'd be surprised if it didn't break something. As an initial assessment, some cases were the compiler would give a CS8917 or CS0176 error would be valid code now. Getting some input/discussions on this would be a great help.

Alternatives

C# 14 extension properties allow thenew keyword to be used on them, but it doesn't appear to do anything at the moment; it could probably be used to adjust its resolution priority somehow.

todo (input/discussions welcome)

Prototype / Proof of Concept

todo

You must be logged in to vote

Replies: 0 comments

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Labels
None yet
1 participant
@LeQuackers

[8]ページ先頭

©2009-2025 Movatter.jp