Access modifiers are keywords used to specify the declared accessibility of
types and type members. The four access modifiers are discussed in the
table below:

Access Modifier

Meaning

public

public is an access modifier
for types and type members. This is the most permissive access level
as there are no restrictions on accessing a public
type or type member.

internal

internal is an access
modifier for types and type members. internal
members are accessible only within file of the same assembly. It is an
error to reference an internal type or internal
type member outside the assembly within which it was declared.

A common use of internal access is in
component-based development because it enables a group of components to
interact in a private matter without being exposed to the outer world. For
example, a Data Access Layer could have several classes with internal
members that are only used by the DAL.

protected

protected is an access
modifier for type members only. A protected
member is only accessible within the body of the containing type and from
within any classes derived from the containing type.

private

private is an access modifier
for type members only. private access is
the least accessible and such members are only accessible within the body
of the containing type.

Note that nested types within the same containing body can also access
those private members.

Accessibility Levels

The four access modifiers listed above result in five accessibility levels
shown below. Note how certain accessibility levels are not permitted
depending on the context in which an access modifiers was used:

Accessibility Level

Meaning

Applies to namespaces

Applies to Types

Applies to Type members

public

Access is not restricted.

Yes

Yes

Yes

internal

Access is limited to the current assembly
(project).

No

Yes

Yes

protected

Access is limited to the containing class, and
classes derived from the containing class

No

No

Yes

internal protected

Access is limited to the current assembly
(project), the containing class, and classes derived from the containing
class

No

No

Yes

private

Access is limited to the containing type.

No

No

Yes

The following table illustrates accessibility levels for namespaces, types, and type
members. Note that namespace elements (i.e., classes, structs, interfaces and
enum) can only have public or internal
declared accessibility. Access modifiers private, protected,
and protected internal are not allowed on namespace
members.

The keyword const is used to modify the
declaration of a field or local variables. It indicates that the value of
the field or local variable cannot be modified. Note the following two points
for using const:

The constant expression used to initialize the constant must yield a value
of the target type, or a value of a type that can be implicitly converted to
the target type.

The constant expression used to initialize the constant must be one that
can be fully evaluated at compile time. Therefore, the only allowable
value for a reference type is either a string or null.

The extern modifier is used in a class member
declaration (method, property, event, indexer, operator, constructor, and
destructor ) to indicate that the method is implemented somewhere else outside
the C# code (externally). extern is usually used
with the DllImport attribute. And because an extern
method should not provide an implementation, there is no method body. For
example:

It is an error to use extern and
abstract modifiers to modify the same member.
abstract modifier means that the method
implementation is not provided in the containing class but should be provided in
derived class, whereas extern means that the method
is implemented outside the C# code.

External Assembly Alias (New in C# 2.0)

Sometimes you may have to use two or more versions of the same
assembly in the same application. In other words, you need to reference
two versions of the same assembly that have the same fully-qualified name. By
using an external assembly alias, the namespaces of each assembly can be
wrapped inside root-level namespaces named by the alias, allowing them to be
used in the same file.

External assembly aliases are accomplished with the alias
sub-option of the /Reference compiler option.
The main procedure is as follows: Suppose you have a Data Access Layer project
called DAL written in VB. You compile this project to produce
DAL_VB.DLL. This DLL is in turn used by a business
objects layer DLL called BOL.DLL. You then rewrite
DAL in C# but only manage to partially finish it. This partially finished code
is now in a DLL called DAL_CS.DLL. Both
DAL_VB.DLL and DAL_CS.DLL
refer to the code base which has the same namespaces. In your
BOL.DLL you still would like to reference both DLLs
- DAL_CS.DLL for the new and improved functionality,
and DAL_VB.DLL for the remaining yet-to-translate
functionality.

You then compile your BOL.DLL with the /Reference option as follows:

/Reference DALVB=DAL_VB.DLL /Reference DALCS=DAL_CS.DLL

This will setup two external references called
DALVB and DALCS, which you can use in the BOL
code via an extern statement as follows:

extern DALVB;
extern DALCS;

// You can now refer to
the same class from both DLLs
DALVB.DAL.ExecuteNonQuery( ... );
// Old DLL
DALCS.DAL.ExecuteNonQuery( ... );
// New DLL

Applies to: classes, structs and interfaces. Does not apply
to delegate and enums.

partial keyword is used to split the
definition of a class or struct or interface across multiple source files. Each
source file would contain a section of the class definition and all parts are
combined when the application is compiled. The following example illustrates:

In large projects spreading a class definition over multiple
source files allows multiple programmers to work on it simulataneously.

When working with automatically generated source code, your code
can be added to the automatically generated source code (in a separate class
using partial keyword) without having to edit the
automatically generated source code. Visual Studio uses this functionality
when creating Windows Forms (and other file types). Consider this code
generated by VS.NET 2005 for a Windows Forms class:

All the parts of a partial definition must use the
partial keyword, and all the parts must be
available at compile time to form the final type. Obviously, all parts must
have the same declared accessibility ( a partial part cannot be
public while another is
internal).

All parts of a partial definition must be defined in the same
assembly.

If any of the parts is declared abstract,
then the entire type is abstract. Likewise, if any of the parts is declared
sealed, then the entire type is sealed.

If any of the parts inherits from a base class, then the entire
type inherits from that class.

Each partial part my inherit from a
different interface, but the final type must implement all the interfaces
listed by the partial class definitions.

Any class,
struct, or interface members declared in a
partial definition are available to all the other parts.

Nested types can be partial, even if the containing type is not
partial

public class MyClass
{
partial class MyPartialClass
{...
}

...

partial class MyPartialClass
{...
}
}

At compile-time, attributes of partial-type definitions are
merged together.

readonly is a modifier that can only be applied
to class fields. A readonly field cannot be assigned
a value during program execution except as part of its declaration or in a
constructor of the same class. See readonly
in Classes section for a full example.

A sealed class is one that cannot be inherited.
It is typically used to prevent accidental inheritance of the class. struct are
implicitly sealed and thus cannot be inherited. See Sealed
Classes in Classes section.

The virtual keyword is used to indicate that the
implementation of the affected class member depends on the runtime-type of the
object being invoked. So when a virtual method is
invoked, the runtime-type of the invoked object is checked for an overriding
member. The overriding member in the most-derived class is then called.

Note the following points:

By default, class members are non-virtual. You cannot override a
non-virtual method.

The virtual modifier cannot be used on declarations with static,
abstract or override.

The volatile keyword indicates that a filed can
be modified in the program by the operating system, hardware, or another
concurrently executing thread. A volatile field is
usually used for fields that will be accessed by multiple threads without using
the lock statement to synchronize access. Using the volatile
modifier ensures that one thread retrieves the most-up-to-date value written by
another field.