csharplang
csharplang copied to clipboard
Champion "Private protected" (C# 7.2, VB 15.5)
- [X] Proposal added: proposals/private-protected.md
- [x] Discussed in LDM (2015-09-08)
- [x] Decision in LDM
- [ ] Finalized (done, rejected, inactive)
- [ ] Spec'ed
I'm still in favor of protectedinternal.
@paulomorgado Do you know why this feature didn't make it into C# 6?
Do you know why this feature didn't make it into C# 6?
The syntax was not good enough? 😁
You know I do, @gafter! 😄
To me, protected internal says that it's protected or any derived class internal. Meaning it is accessible to any derived class or any type in the same assembly.
protectedinternal says to me protected and internal. Meaning it is accessible to any derived class in the same assembly.
protectedinternal wouldn't be the first multi word keyword.
Any other proposal either doesn't look like anything seen in C# in the last 15+ years or builds on top of not using protectedinternal introducing different ways to do the same thing.
Oh not this again. protectedinternal suffers from the problem of being excessively long and not different enough (not everyone uses monospace fonts in their IDEs). My opinion is that the team should just go with private protected or whatever combination of keywords they want and ignore the 500 other options that aren't any better. I'm fine with private protected. C++/CLI already uses it for this very accessibility modifier.
In fact, I think protectedinternal is even more confusing as it's only different in a single whitespace. Also, the fact that private protected doesn't need syntax changes, makes it more preferable IMO.
If there is planned work in this area I'd like to see also introduction of private internal to control if internal types/members are affected by InternalsVisibleTo.
The idea is to use private internal if you don't want your internal types/members be visible outside of an assembly when InternalsVisibleTo is used.
Does the CLR even support such a scenario, or does such a hypothetical private internal maybe not need CLR support?
@Joe4ever This is pure language feature, no CLR involvement
@marek-safar
IIRC, using private internal as you suggested would require CLR changes as how InternalsVisibleToAttribute works is governed by the CLR.
And it should be a separate proposal.
Just to be clear everybody, the precise syntax had been debated ad nauseum a few years ago and this is the winner. If we do the feature the syntax will be private protected. If the community really hates that then we simply won't do the feature.
@gafter,
Just to be clear everybody, the precise syntax had been debated ad nauseum a few years ago and this is the winner. If we do the feature the syntax will be private protected. If the community really hates that then we simply won't do the feature.
That has defeat written al over it.
Currently, access modifiers worked as a union. When more than one is allowed, each one retains the same semantics. If something is protected it doesn't change its "protectiveness" by adding or removing the internal modifier. That doesn't happen with the proposed solution.
I "hate" it because it hinders the learning of the language and the understanding of the code.
I know my proposal has a drawback that, regardless of the font used, an acidental removal or insertion of a white space will change the meaning of the program.
And I don't care that C++/CLI made the same mistake.
At this point I would prefer some new keyword like shielded or sheltered.
private protected makes enough sense. It's fine that it isn't purely etymologically consistent. No one thinks through the logic anyhow; it's just a convention we've memorized. Also, subjectively, private protected is the least awkward sounding name I've heard so far.
@paulomorgado: This has been debated over and over again. There is no good solution. It's either private protected or we'll never get the feature. I'm not happy with private protected either, but I also don't have a better solution. So let's just live with that and let's get that feature into the language!
@paulomorgado internally protected.
@axel-habermaier, looks like it hasn't been debated long enough.
Any outcome that is not a single keyword is not a cure. It's just a Band-Aid that we'll have to live with forever.
@paulomorgado
Yeah, it has been debated enough. The team should either execute or drop.
This is a feature with such a limited use case that it doesn't deserve the kind of debate that it's already received. It doesn't solve any problems. It's at most a tool to help developers not use their own source incorrectly.
And protectedinternal is awful. Not everyone uses monospace fonts and that whitespace will be totally lost, assuming someone doesn't fat-finger and mess it up to begin with.
@paulomorgado, having a language construct that is created from multiple keywords is not that unusual. In some cases, like C++ they separate the words with underscore (thread_local for example). The use case here is potentially small, and the way it is constructed makes sense and will be familiar to anyone who has declared similar types before (such as in C++/CLI).
@tannergooding,
What other keyword in C# uses underscore?
What other language construct in C# uses more than one keyword?
__arglist, __refvalue, __makeref, __reftype for one.
language construct in C# uses more than one keyword?
yield return or all other modifiers?
using static as well
I'd say async/await is a single language construct that uses more than one keyword to express.
@bbarry Actually wait for was also considered before await just that it did not require async.
I knew that, if gave enough rope, plenty would jump to wrap it around their necks. 😄
__arglist,__refvalue,__makeref, `__reftype
These keywords are not on the list of the C# keywords on the documentation or the C# Language Specification. If the recommendation is for this feature to be tuck away hidden from the non illuminati, then, by all means, __protected_internal.
yield return
I would argue that yield is one thing and return and break another. But, yes, they are the Yield Statements, not the Yield Statement.
other modifiers
Which ones? Are you counting protected internal and internal protected as two. Or are you saying that abstract, virtual, abstract, override or async are access modifiers?
using static
I would argue that static is part of the argument of the using directive which is a one keyword only construct. Just that until now there was no need for using namespace ... and using alias .....
async/await
Hardly. I can use async without any await, although I can only use one or more awaits with one async.
In any case, async is a method modifier and await is, like yield, some sort of statement modifier.
-_-
I wonder why it's private protected and not private internal. What makes protected part of protected-and-internal more important than internal part?
I'd rather have something messy like protected&internal and protected|internal (with protected internal left for compatibility) than a combination of keywords that leaves out 50% of information it needs to convey. 😕
Head meets desk.
@alrz What?
I know I'm late to the party. Like, 3 years late or so. But I still find private protected FUBAR.
@Athari https://github.com/dotnet/csharplang/issues/37#issuecomment-280013888 Also, people are incredibly tired of the argument. Perpetuating the argument has prevented and will continue to prevent this useful feature from appearing in any form.
@jnm2 When did private protected win, by the way? It lost badly in the poll on CodePlex. Just because of C++/CLI?