You have already encountered quite a number of so-called modifiers - keywords that can be applied to a type or to a member. Modifiers can indicate the visibility of a method, such as public or private, or the nature of an item, such as whether a method is virtual or abstract. C# has a number of modifiers, and at this point it’s worth taking a minute to provide the complete list.
Visibility modifiers indicate which other code items can view an item.
Modifier | Applies To | Description |
---|---|---|
public | Any types or members | The item is visible to any other code. |
protected | Any member of a type, also any nested type | The item is visible only to any derived type. |
internal | Any member of a type, also any nested type | The item is visible only within its containing assembly. |
private | Any types or members | The item is visible only inside the type to which it belongs. |
protected internal | Any member of a type, also any nested type | The item is visible to any code within its containing assembly and also to any code inside a derived type. |
Note that type definitions can be internal or public, depending on whether you want the type to be visible outside its containing assembly.
public class MyClass { // etc.
You cannot define types as protected, private, or protected internal, because these visibility levels would be meaningless for a type contained in a namespace. Hence these visibilities can only be applied to members. However, you can define nested types (that is, types contained within other types) with these visibilities, because in this case the type also has the status of a member. Hence, the following code is correct:
public class OuterClass { protected class InnerClass { // etc. } // etc. }
If you have a nested type, the inner type is always able to see all members of the outer type. Therefore, with the preceding code, any code inside InnerClass always has access to all members of OuterClass, even where those members are private.
The modifiers in the following table can be applied to members of types and have various uses. A few of these modifiers also make sense when applied to types.
Modifier | Applies To | Description |
---|---|---|
new | Function members | The member hides an inherited member with the same signature. |
static | All members | The member does not operate on a specific instance of the class. |
virtual | Classes and function members only | The member can be overridden by a derived class. |
abstract | Function members only | A virtual member that defines the signature of the member, but doesn’t provide an implementation. |
override | Function members only | The member overrides an inherited virtual or abstract member. |
sealed | Classes | The member overrides an inherited virtual member, but cannot be overridden by any classes that inherit from this class. Must be used in conjunction with override. |
extern | static [DllImport] methods only | The member is implemented externally, in a different language. |
Of these, internal and protected internal are the ones that are new to C# and the .NET Framework. internal acts in much the same way as public, but access is confined to other code in the same assembly - that is, code that is being compiled at the same time in the same program. You can use internal to ensure that all the other classes that you are writing have access to a particular member, while at the same time hiding it from other code written by other organizations. protected internal combines protected and internal, but in an OR sense, not an AND sense. A protected internal member can be seen by any code in the same assembly. It can also be seen by any derived classes, even those in other assemblies.