To promote encapsulation, a type or type member may limit its accessibility to other types and other assemblies by adding one of five access modifiers to the declaration:
public
Fully accessible. This is the implicit accessibility for members of an enum or interface.
internal
Accessible only within containing assembly or friend assemblies. This is default accessibility for non-nested types.
private
Visible only within containing type. This is the default accessibility for members of a class or struct.
protected
protected internal
The union of protected
and
internal
accessibility (this is
less restrictive than protected
or internal
alone).
In the following example, Class2
is accessible from outside its assembly; Class1
is not:
class Class1 {} // Class1 is internal (default)
public
class Class2 {}
ClassB
exposes field x
to other types in the same assembly; ClassA
does not:
class ClassA { int x; } // x is private
class ClassB { internal
int x; }
When overriding a base class function, accessibility must be identical on the overridden function. The compiler prevents any inconsistent use of access modifiers—for example, a subclass itself can be less accessible than a base class, but not more.
In advanced scenarios, you can expose internal
members to other
friend assemblies by adding the
System.
Runtime.
Compiler
Services.
InternalsVisibleTo
assembly attribute, specifying the name of the friend assembly as
follows:
[assembly: InternalsVisibleTo ("Friend")]
If the friend assembly is signed with a strong name, you must specify its full 160-byte public key. You can extract this key via a LINQ query—an interactive example is given in LINQPad’s free sample library for C# 4.0 in a Nutshell (O’Reilly).
A type caps the accessibility of its declared members. The most
common example of capping is when you have an internal
type with public
members. For example:
class C { public void Foo() {} }
C
’s (default) internal
accessibility caps Foo
’s accessibility, effectively making
Foo internal
. A common reason
Foo
would be marked public
is to make for easier refactoring,
should C
later be changed to public
.