63

I tried to make a class as private and got this Error "Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal"

I got its meaning but I want to ask why this is not allowed? Are all access modifires not applicable on Class? Why I can't make a class private, protected or protected internal?

0

9 Answers 9

81

Because private means that the member is only visible in the containing class. Since a top-level class has no class containing it it cannot be private (or protected). (Internal or public are valid modifiers though).

What would you want private to mean on a top-level class?

Of course all modifiers apply to nested classes, i.e. a class defined within another class.

Sign up to request clarification or add additional context in comments.

7 Comments

What if I want a class to be visible for only classes in a particular namespace ? how to do that, without having to move the class inside another one ?
Basically you can't. This would be kind of a strange feature to have if you ask me, since the same namespace can exist in multiple assemblies for example.
Thanks, I guess java has something like package level access or similar, I will look at it..
I disagree with that explanation. This has nothing to do with containing classes. Ahmed feeling makes perfect sense, at least as a C++ programmer for example, where namespace and class are quasi-synonyms. The real explanation is that C# has chosen that namespaces are far from being equivalent to classes, and accessibility is not configurable at all in namespaces. public and internal when used in namespaces are merely language support for dll export of symbols. Therefore, the language is disturbing because they recycled keywords. They should have allowed only one qualifier: exported.
I want my class not to be available outside of assembly except for inheritance hence I am using "protected internal". Can anyone explain why I am getting the error in question?
|
14

You can use only public or internal in the Namespace level

Comments

5

As Abatonime said, you can only use public or internal in the Namespace level.
private, protected, or protected internal can only be used in the Class level.

This works

namespace X { class A { // class code here private class B // this class is an inner class { // class code here } } } 

This won't

namespace X { class A { // class code here } private class B // this is a class inside a namespace { // class code here } } 

Comments

3

Because it doesn't make sense. There's no way you can access protected or private classes defined at namespace level, only as nested classes.

2 Comments

Now that you said that private doesn't make sense, try to justify why public makes sense, without contradicting yourself. And since we can't write private, then what is a class without access qualifier ? No gentlemen, here, definitely, it is C# that doesn't make sense. private would mean only visible in this namespace, and internal private would mean this namespace in this assembly. It makes perfect sense on the contrary.
@v.oddou: not sure if it's C# of CLR limitation. anyway, i too would prefer more granular access modifiers (like in Scala perhaps). but current design is solid enough for me and doesn't bother or limit me, unlike many other c# flaws.
2

Only nested classes could be declared as private. Not nested classes can be only public or internal (implicit without modifiers)

Comments

1

I had this same problem because I was creating a custom DLL and only wanted certain classes to be visible to an application using the DLL. So I just remove the modifier completely for classes I wanted to be private (within specific namespaces). The classes remained accessible to other classes within the same namespace in the DLL but did not show up in Intellisense in the calling application. No need for nested classes. The only explanation I can think of is the error message says cannot "explicitly" declare private...it doesn't say anything about implicitly.

namespace SmartCardAuthentication { class SmartCardIdentity : IIdentity { private string _firstName; private string _lastName; private string _middleInitial; .... } } 

In example code above, class "SmartCardIdentity" is available to other class within same namespace, but not available to calling application when this class is rolled into a DLL. I have not tested it anyother way (i.e. visibility from a class in a different namespace within the DLL.).

Comments

0

The default accessibility of top-level types is internal.

The default accessibility of class and struct members is private.

The only possible accessibility of interface and enum members is public.

So a class is by default private, and if you want to access that, you have to put public before that.

1 Comment

The question is talking about access specifiers on classes (specifically, top-level classes), not class members. This answer doesn't answer the question asked and "a class is by default private" is simply incorrect.
0

Only Public and Internal are applicable when defining class. If no access modifier is defined before the class default is internal.

refer to MSDN - [https://msdn.microsoft.com/en-us/library/8fd16xs0(v=vs.90).aspx]

Comments

0

In real world we are focus on visible object Once object is visible then we talk about scope of the object

example in real world

If you walking on street, you see houses in a colony colony has houses. If colony is protected no one can't able to see houses It is consider that no colony no houses is present

In Programming

If we make class as private/ protected at top-level no one known about it

is it present in assembly ?

please correct me, if i am out of the scope

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.