-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: language support for Obsolete #11583
Comments
This sounds like it would cause nightmares in cross language and cross version support. The existing compilers don't play well with methods that are overloaded by return type. As long as C# can target earlier frameworks there will always be the likelihood that a C# 9.0 binary will need to be consumed by a project written and maintained in Visual Studio 2005, likely by one of those large influential customers who would be very pissed off if any behavior changed on them. |
In practice causing enterprise harm is not really a big consideration for Microsoft to be honest: https://medium.com/swlh/how-one-announcement-destroyed-the-net-ecosystem-on-windows-19fb2ad1aa39 |
How Microsoft treats new and isolated platforms isn't relevant to their general behavior of obsessively maintaining backward compatibility. Microsoft did not break how existing .NET apps worked or built on Windows 8 or Windows 10. This proposal demonstrates they're relatively obsessive about ensuring forward compatibility between versions of the .NET framework and compilers to the extent that no new warnings can be added or existing members marked obsolete. In general I applaud Microsoft for their efforts here, but I do think that they take it a bit far. Other widely used enterprise languages do add new warnings or breaking changes. For example, Java 8 added a new warning about using |
The two scenarios don't sound convincing to me: In scenario 1, you have to keep the old overload around for binary compatibility, so it has to keep working. Then what is the advantage to hide the overload when recompiling? The one I can see is that the user gets to see only the new overload, but that doesn't seem like a big advantage to me. In scenario 2, you're changing the return type of a method, which is a source breaking change. So what's the point of avoiding binary breaking change? When the user recompiles, the code will (potentially) break anyway. Another point I don't like is the syntax: The compiler already treats |
We are now taking language feature discussion in other repositories:
Features that are under active design or development, or which are "championed" by someone on the language design team, have already been moved either as issues or as checked-in design documents. For example, the proposal in this repo "Proposal: Partial interface implementation a.k.a. Traits" (issue 16139 and a few other issues that request the same thing) are now tracked by the language team at issue 52 in https://github.com/dotnet/csharplang/issues, and there is a draft spec at https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md and further discussion at issue 288 in https://github.com/dotnet/csharplang/issues. Prototyping of the compiler portion of language features is still tracked here; see, for example, https://github.com/dotnet/roslyn/tree/features/DefaultInterfaceImplementation and issue 17952. In order to facilitate that transition, we have started closing language design discussions from the roslyn repo with a note briefly explaining why. When we are aware of an existing discussion for the feature already in the new repo, we are adding a link to that. But we're not adding new issues to the new repos for existing discussions in this repo that the language design team does not currently envision taking on. Our intent is to eventually close the language design issues in the Roslyn repo and encourage discussion in one of the new repos instead. Our intent is not to shut down discussion on language design - you can still continue discussion on the closed issues if you want - but rather we would like to encourage people to move discussion to where we are more likely to be paying attention (the new repo), or to abandon discussions that are no longer of interest to you. If you happen to notice that one of the closed issues has a relevant issue in the new repo, and we have not added a link to the new issue, we would appreciate you providing a link from the old to the new discussion. That way people who are still interested in the discussion can start paying attention to the new issue. Also, we'd welcome any ideas you might have on how we could better manage the transition. Comments and discussion about closing and/or moving issues should be directed to #18002. Comments and discussion about this issue can take place here or on an issue in the relevant repo. I am not moving this particular issue because I don't have confidence that the LDM would likely consider doing this. |
Background
In C#6, we can basically never remove nor obsolete an old method:
I propose we add language support for Obsolete:
Proposal
Syntax
Add a new method modifier
obsolete
Semantics
obsolete(...,false)
which is less obsolete thanobsolete(...,true)
. I'm using false=warning and true=error here, just the same as the[Obsolete]
attribute.obsolete
modifier on something that also has an[Obsolete]
attributeobsolete(s,b)
implies[Obsolete(s,b)]
, along with all the associated warnings+errors that this impliesobsolete
modifier is not considered part of a method's signature.Mp
is a better function member thanMq
. This will be amended with an even more important preliminary check: a less obsolete function memberMp
is always better than a more obsolete memberMq
.Compilation
Confusingly, we have to prevent
obsolete
from itself being a back-compat break. Here's the scenario we have to worry about: (1) A user of C#6 references a library which usesobsolete
methods, but C#6 is unaware of them, and so picks a more obsolete overload candidate; (2) the user of C#6 upgrades to a version of C# with this proposal, which now changes the overload candidate.We can't make the
obsolete
modifier be amodreq
because the CLR treats modreqs as part of a method's signature, and so adding the modifier would break binary compat. This would defeat the entire point of the proposal.Therefore: we will emit
obsolete(s,b)
as[Obsolete(s,b), ObsoleteModifier]
. C#7 should recognize this[ObsoleteModifier]
attribute on a method when it meta-imports, and mark the method and all its overloads as bad.Later on, once we've seen that usage of C#6 has declined sufficiently, then we introduce the feature proper into C#8 or C#9, safe in the knowledge that it won't be a severe back-compat break.
The text was updated successfully, but these errors were encountered: