Sep 06

Type visibility vs member accessibility

Posted in Basics C#      Comments Off on Type visibility vs member accessibility

One of the things I’ve noticed while trying to help others get started with the .NET framework is that they tend to confuse type visibility with member accessibility. In this quick post I’ll try to point out the differences between these two concepts. Let’s start with type visibility.

When you create a type (ex.: class, struct, etc.) it may be visible to all the code (public keyword) or only to the types defined in the same assembly as that type (internal keyword). In C#, you can use the public or the internal qualifier to define the visibility of a type. By default, all the types which haven’t been explicitly qualified with one of these keywords is considered to be internal:

//internal by default
struct T {
//… }

Member accessibility is all about specifying the visibility of the members of a type. In other words, the accessibility indicates which members might be accessed from some piece of code. Currently, the C# allows you do use 5 of the 6 supported CLR member accessibility options:

  • private: members qualified with the private keyword (C#) are only accessible by other members defined in the same type or in a nested type.
  • family: members qualified with the protected keyword (C#) can only be accessed by methods in the defining type, nested type or one of its derived types.
  • family and assembly: you *can’t* use this accessibility in C#. This accessibility says that a member can only be used by methods in the same type, in any nested type or in any derived type defined in the *same* assembly as the current type.
  • assembly: in C#, you use the internal keyword to specify this accessibility level. In this level, the member can only be accessed by all the types defined in the same assembly as the current type.
  • family or assembly: in C#, you need two keywords to specify this level: protected internal. In practice,it means that the member is accessible by any member of the type,any nested type, any derived type (*regardless* of the assembly) or any other method in the same assembly as the current type.
  • public: members qualified with the public keyword (C#) can be used by any other member in any assembly.

Before going on, it’s important to notice that member accessibility depends always in the visibility of the type. For instance, public members exposed by an internal type in assembly A *cannot* be used from assembly B (by default) since the type isn’t visible in that assembly.

In C#, if you don’t specify the accessibility of a member, the compiler will default to private in most cases (one exception: interface methods are always defined as public!). In C#, when you override a member in a derived type, you must use the same accessibility as defined in the base class. Interestingly, this is a C# restriction since the CLR does allow you to change the accessibility of a member in a derived class to a less restrictive level (ex.: you can go from private to protected in the override, but not the other way around).

There’s still a couple of things I have to say about member accessibility, but I’ll leave it for a future post. Stay tuned for more.