- Notifications
You must be signed in to change notification settings - Fork1.1k
Proposal: Adjust Member Resolution Algorithm Priority Based on if the Receiver Is Static or an Instance#9525
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
The ProblemA 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:
Proposed SolutionPrioritize members based on if the receiver is static or an instance, i.e.:
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 RiskAt 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 a 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. DrawbacksI 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 ChangesThe 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. AlternativesC# 14 extension properties allow the todo (input/discussions welcome) Prototype / Proof of Concepttodo |
BetaWas this translation helpful?Give feedback.