What kind of access modifiers can be applied to a class? - c#

After a little research I've determined that the only access modifiers which you can apply to classes are:
public - available in any assembly
internal - available only in the current assembly
but the error message below seems to imply that if a class is not defined in a namespace that it could be defined as private, protected, or protected internal.
Are public and internal the only class modifiers you can use on class or are there more?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test2343434
{
class Program
{
static void Main(string[] args)
{
Tools.ToolManager toolManager = new Tools.ToolManager();
Console.ReadLine();
}
}
}
namespace Tools
{
//error: Elements defined in a namespace cannot be explicitly
//declared as private, protected, or protected internal
private class ToolManager
{
public ToolManager()
{
Console.WriteLine("inside tool manager");
}
}
}

A nested type can be declared private, protected, or protected internal. You can still declare nested types as public or internal of course - it's just that you can only declare them with the above access modifiers when they're nested:
public class OuterClass
{
private class PrivateNested {}
protected class ProtectedNested {}
protected internal class ProtectedInternalNested {}
public class PublicNested {}
internal class InternalNested {}
}
Note that you can't declare a type nested in a struct to be protected or protected internal because it doesn't make any sense to do so :)
public struct OuterStruct
{
private class PrivateNested {}
public class PublicNested {}
internal class InternalNested {}
}
C# doesn't allow types to be nested in interfaces (unfortunately, IMO - it would be useful for code contracts).
All of this is true for other nested types (enums, structs, interfaces, delegates) too.

Take a look at this MSDN page:
Type declarations in a namespace can have either public or internal access. If no accessibility is specified, internal is the default.
It makes little sense for a type declaration in a namespace to be anything other than public to external assemblies, or internal (C# does not support the concept of friend classes or anything like that).

The answer is found in Accessibility Levels.
A "top-level" class, i.e. not nested in another class, can only be public or internal. By default (if you don't declare anything), it is internal.
Nested classes can have all five possible accessibility levels, i.e. public, protected, internal, private, protected internal.

In the context of this question it might be interesting to point out that there is a not so well known mechanism for making internal classes visible to other assemblies. That mechanism is the InternalsVisibleTo attribute. It is not considered one of the access modifiers by any stretch, but does have the effect of manipulating who has access. The concept is referred to as friend assemblies.

Related

What is the use case for the (C# 7.2) "private protected" modifier?

C# 7.2 introduces the private protected modifier.
I've always protected access to fields with properties, allowing access via the Get/Set methods as I typically don't want the internal state of my object modified by anything other than my own class.
I'm trying to understand why the C# language team have added this feature. After an extensive search on google, and reading and watching the 'what's new' media (I've watched the press release, details and video by Mads Torgerson), I am still none the wiser.
To me, this appears to allow a developer to break the Liskov Substitution principle, but this may be because I do not understand why this feature now exists.
I understand how it can be used, just not why - please can someone provide a real-world usage example rather than the contrived one in the MSDN documents?
Before C# 7.2 we had protected internal modifier. This really means protected OR internal, that is - member A is accessible to child classes and also to any class in the current assembly, even if that class is not child of class A (so restriction implied by "protected" is relaxed).
private protected really means protected AND internal. That is - member is accessible only to child classes which are in the same assembly, but not to child classes which are outside assembly (so restriction implied by "protected" is narrowed - becomes even more restrictive). That is useful if you build hierarchy of classes in your assembly and do not want any child classes from other assemblies to access certain parts of that hierarchy.
We can take example that Jon Skeet provided in comments. Suppose you have class
public class MyClass {
}
And you want to be able to inherit from it only in current assembly, but do not want to allow to instantiate this class directly except from within this class hierarchy.
Inheriting only within the current assembly may be achieved with internal constructor
public class MyClass {
internal MyClass() {
}
}
Preventing direct instantiation except withing current class hierarchy may be achieved with protected constructor:
public class MyClass {
protected MyClass() {
}
}
And to get both - you need private protected constructor:
public class MyClass {
private protected MyClass() {
}
}
For two-word access modifiers I have this concept - the first accessor is related to another assembly, the second one to that assembly in which it was defined.
protected internal
protected in another assembly: accessible only in the child classes.
internal in the current assembly: accessible by everyone in the current assembly.
private protected
private in another assembly: is not accessible.
protected in the current assembly: accessible only in the child classes.
Lets suppose that you have an internal class called SomeHelper that you want to use as part of the implementation of a public abstract base class:
public abstract class Test
{
// Won't compile because SomeHelper is internal.
protected SomeHelper CreateHelper()
{
return new SomeHelper();
}
public int Func(int x)
{
var helper = CreateHelper();
return helper.DoSomething(x);
}
}
internal class SomeHelper
{
public virtual int DoSomething(int x)
{
return -x;
}
}
This won't compile because you cannot have a protected method returning an internal type. Your only recourse is to not use SomeHelper in that way, or to make SomeHelper public.
(You could make SomeHelper a protected inner class of Test, but that's not going to work if SomeHelper is intended for use by other classes that don't derive from the base class.)
With the introduction of the private protected feature, you can declare CreateHelper() like so:
private protected SomeHelper CreateHelper()
{
return new SomeHelper();
}
Now it will compile, and you don't have to expose your internals.
protected internal
implies to "protected or internal" - any type/member defined with this access modifier can be accessed in the following scenarios - (A) in the same assembly, (B) class which is defined in another assembly and derives from the container class
private protected
implies to "protected and internal" - any type/member defined with this access modifier can be accessed in the following scenario - class that inherits from the container class and belongs to the same assembly

If I declare an internal class, what the default access level of internal members be?

I'm building a DLL with some basic functions. Long story short, I'm making a few static classes for the use by devs. These classes use some other classes that do the dirty work, which I marked as internal because I don't want people to access them.
The question is: If I declare a class as internal, what the access level of his members will be?
I'll have to mark as internal all of its members or they are automatically labeled as internal too?
It's a good 2 hours I'm googling and searching in stackoverflow and I'm struggling to find a clear and straight answer which doesn't include 1000 speculations, technical not-so-probable hypotesis and useless decorations...
MSDN is confusing as usual (never found a clear answer on msdn).
From what I can read here http://msdn.microsoft.com/en-us/library/ms173121.aspx I guess that no matter how you set a class access level, all his members will be private (methods, variables and so on).
Help, I don't know
The question is: If I declare a class as internal, what the access
level of his members will be?
The default will be private. If anything else, then it depends. If they are anything other than public, then the access modifier applies as described on MSDN (e.g. not visible outside of the assembly).
However, in the link you posted, there is one gotcha which applies to non-static classes:
Normally, the accessibility of a member is not greater than the
accessibility of the type that contains it. However, a public member
of an internal class might be accessible from outside the assembly if
the member implements interface methods or overrides virtual methods
that are defined in a public base class.
In relation to the last paragraph, since static classes cannot implement interfaces or inherit other classes then you can rest assured. As long you declare your static class internal, the members will not be available in other assemblies (unless your devs use reflection).
To exemplify how it does work for non-static classes:
Assembly 1
public interface ISomePublicInterface
{
int GetValue();
}
internal class InternalClass : ISomePublicInterface
{
public int GetValue()
{
return 100;
}
}
public static class SomeFactory
{
public static ISomePublicInterface GetInternalInstanceAsInterface()
{
return new InternalClass();
}
}
Assembly 2
ISomePublicInterface val = SomeFactory.GetInternalInstanceAsInterface();
Console.WriteLine(val.GetValue()); //-->> Calls public method in internal class
Console.WriteLine(val.GetType());
Guess what the output is?
Assembly1.InternalClass
So, now you have access to the type outside of the assembly and via reflection someone could call other internal methods (it's not the only way to get it).
From MSDN only
The access level for class members and struct members, including
nested classes and structs, is private by default.
interfaces default to internal access.
Hope this table helps:
Members of Default member accessibility
---------- ----------------------------
enum public
class private
interface public
struct private
Also check this MSDN
Private unless otherwise stated. However, public will have same result as internal.
If you later promote a class from internal to public, then creating public class objects will become visible, whilst internally scoped methods will stay internal.
You might want to consider behaviour in case your class scope gets updated.
Another stack overflow question.
If u Declare any class as "internal" then its means you can access this class in same assembly. But what kind of access specifier you use for class member is decide they are accessible are not in different class in same assembly.
All the members of internal class would be internal and will be accessible with in the same assembly and will not be outside neither class nor members.
If you want to access class in other assemblies, make the class public and member you don't want to be accessed outside assembly make them internal.

Protected internal class inside a namespace compiles without error

protected internal class foo
{
//this compiles without any errors
}
also
internal class bar
{
public int quix;
protected internal int zyx;
//this compiles without any errors
}
Are these compiler bugs or my misinterpretation of the standard?
Explanation:
Classes can't have protected internal access modifier, only public or internal according to MSDN (Classes and structs that are declared directly within a namespace (in other words, that are not nested within other classes or structs) can be either public or internal. Internal is the default if no access modifier is specified).
Not all access modifiers can be used by all types or members in all contexts, and in some cases the accessibility of a type member is constrained by the accessibility of its containing type (MSDN). Public should fail. Protected internal is ambiguous for me - internal modifier is not necessary.
Edit: The fact that I'm using Mono is unnecessary cause the question was about what standard says and not what MONO does or does not. Maybe I'm coding my own compiler. That's why I quoted MSDN to be precise what is allowed and what is not.
As mentioned in my comment above, protected internal means protected or internal NOT protected and internal. No bug here :)
Further information/explanation is on haacked
In response to your questions:
A class within a namespace (and not within another class) can only be declared as public or internal. HOWEVER, a class within another class can be declared as protected internal, private, etc.
Yes, protected internal can be used inside a class whose access modifier is more strict than it's members, see example of a perfectly valid usage below (note that the class is inside the Program class):
public class Program
{
static void Main(string[] args)
{
}
private class Foo
{
private int priv { get; set; }
protected internal int protint { get; set; }
public int pub { get; set; }
}
}
From Access Modifiers (C# Programming Guide)
protected internal
The type or member can be accessed by any code in the assembly in
which it is declared, or from within a derived class in another
assembly.
To quote the MSDN entry on this:
protected internal
The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly. Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.
So the declaration makes perfect sense, it's just working differently as expected when used outside a class.
In addition, I really doubt that the "protected and internal class" would ever compile if the class was declared as a member of some namespace:
C# compiler said:
Elements defined in a namespace cannot be explicitly declared as
private, protected, or protected internal
Protected classes will be always nested classes!
UPDATE
Since you're trying your code sample in some version of Mono compiler, and you said in your sample code in your question //this compiles without any errors, I couldn't understand why you didn't tagged the question for Mono.
The standard is the Microsoft C# compiler behavior. If you ask a question about "why something compiles" and you don't mention that you're not using the official one, you're just making the assumption that any compiler would compile your code.
Do you want to know which is the standard? It's -again-: Protected classes will be always nested classes!
Keyword protected belongs to inheritance and keyword internal belongs to scope.

Does C# need the private keyword?

(inspired by this comment)
Is there ever a situation in which you need to use the private keyword?
(In other words, a situation in which omitting the keyword would result in different behavior)
public class Foo
{
public int Bar { get; private set; }
}
Omitting the word 'private' would change the accessibility.
a situation in which omitting the keyword [private] would result in different behavior
David Yaw's answer gave the most usual situation. Here is another one:
In Account_generated.cs:
// Generated file. Do not edit!
public partial class Account
{
...
private partial class Helper
{
...
}
...
}
In AccountHandCoded.cs:
public partial class Account
{
...
public partial class Helper
{
...
}
...
}
The above code will not compile. The first "part" of Account requires the nested class Helper to be private. Therefore the attempt by the hand-coder to make Helper public must fail!
However, had the first part of the class simply omitted the private keyword, all would compile.
So for partial classes (and structs, interfaces), the access-level-free declaration
partial class Name
means "the other 'parts' of this class are allowed to decide what the accessibility should be".
Whereas explicitly giving the default accessibility (which is internal for non-nested types and private for nested ones) means "this class must have the most restricted access possible, and the other 'parts' cannot change that fact".
private isn't about the runtime behaviour. It's to make your application maintainable. What's hidden by private can only ever affect the code outside its class through the public or protected members.
So the answer is 'no' for runtime behaviour, 'yes' for developer behaviour!
In C# version 7.2 and later.
The private protected keyword combination is a member access modifier. A private protected member is accessible by types derived from the containing class, but only within its containing assembly.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/private-protected

My C# Private Class is accessible anywhere inside the DLL, then whats the use of internal?

I have ClassLibrary project in C# and all my 'private classes' (under different namespace) are accessible to each other inside the same assembly (project).
Class1.cs
----------------------------
namespace MyClass1App
{
private class Class1{}
}
Class2.cs
----------------------------
namespace MyClass2App
{
private class Class2{}
}
Now Class1() can access and create instance of Class2() class [like... new MyClass2App.Class2() ]. and yes, these classes (Class1() and Class2()) are not accessible outside the assembly. Its the same behavior when these classes are made as 'Internal'. Can someone help me understanding whats the actual use/difference of 'private' and 'internal' access specifiers when applied on class level?
Thanks!
For normal classes you can only apply public and internal other access modifiers don't make sense.
Nested classes can have all access modifiers types.
You should not be able to declare a class as private at the namespace level. You can only have a private class if it is embedded within another class.
I get an error if I try to do this:
namespace MyApp
{
private class Class1
{
}
}
This is the error message:
Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal
Access Modifiers (C# Programming Guide)
Class or struct members can be
declared with one of five types of
access. They can be public or
internal, like the classes and structs
themselves. A class member can be
declared as protected using the
protected keyword, meaning that only
derived types using the class as a
base can access the member. By
combining the protected and internal
keywords, a class member can be marked
protected internal — only derived
types or types within the same
assembly can access that member.
Finally, a class or struct member can
be declared as private with the
private keyword, indicating that only
the class or struct declaring the
member is allowed access to that
member.
Duplicate Question:
Internal vs. Private Access Modifiers

Categories