.NET: Encapsulation, hiding and member binding in C#

by Stephen Horsfield 20. May 2008 09:30

I've been looking at the C# specification for the new keyword when used on a class member declaration and thought I'd share my findings.  If you are a die-hard C# coder then you won't find anything new here, but of course that doesn't mean that you already know it!  Maybe it would be better to check...

The basics

Encapsulation

Encapsulation is a term used in object-oriented design.  It describes the idea of wrapping some functionality in an outer shell.  The outer shell may contain significant functionality or it may just adapt the behaviour of the contained code.

Further, encapsulation protects the consumer of a class from needing to know about the internal operation of that class.  It allows the programmer to code against a contract of function, rather than needing to know the detail of its implementation.

Binding modes and invocation

In C#, and in .NET in general, there are two modes of member binding and invocation.  In this post, compile-time-binding means that the compiler determines what to use and runtime-binding means that the CLR determines what to use.  This will be precisely defined in what follows, after introducing some other terms and keywords.

The "virtual" and "override" keywords

The virtual keyword is used to allow a derived class to change or specify the behaviour of the inherited class.  This is usually used for methods but can also be used for properties.  There are some constraints: the method signature must match.  Additionally, in the inherited class the override keyword must be used to indicate that the method is intended to be an implementation of the virtual method.

The "new" keyword

The new keyword is used to indicate that a member of a derived class with the same name as a member of the inherited class has that name because the author intended to "hide" the member in the inherited class.

Note:  the "new" and "override" keywords are mutually exclusive, however "new" and "virtual" can be used together.

Context

Virtual methods are used throughout the .NET framework.  They allow you to extend the functionality of a class for specific cases.  Sometimes though, a method or property that you would like to be marked as virtual is not.  In these cases, the override keyword cannot be used.

The new keyword is not used frequently as it has the effect of hiding the member of the parent class, though with some important caveats that I'll come on to.  Its main use is to simplify the use of the inherited class by "hiding" certain functionality.

A particular problem is when you wish to encapsulate some code over which you have no control.  The question is then how to encapsulate the code efficiently, whether the issue is the performance of the solution or the time required to implement it.  I recently posted about a specific example of this, using a ComboBox control to allow the selection of an enumeration value.

In detail

The virtual keyword indicates to the compiler that the invocation of a method should be bound at runtime.  This is more expensive than compile-time-binding, and also prevents certain optimisations and so it is not the default behaviour.  In every case that the virtual keyword is not specified and not implied (by a derived class using the override keyword, for example), compile-time-binding is used.  Only the virtual keyword instructs the compiler to use runtime-binding.

How does runtime-binding work?  In both compile-time-binding and runtime-binding, the compile determines the member to use on the basis of compile-time type information.  Only the invocation is different.  This is essential to a proper understanding of the virtual and new keywords, particularly when used together.  The compile-time type of the object determines member selection.

What does this mean for us?  This means that the member selected may differ depending on the declared type of the object.  It means that the virtual keyword does not play any role in the selection of a type member to use.

So what does the virtual keyword do?  The virtual keyword changes the invocation behaviour.  When applied, the bound member is invoked on the derived type.  For a non-virtual member, the member is invoked on the declared type.

What about the new keyword?  The new keyword specifies that a new member with the same name exists in the derived type in addition to the pre-existing member of the inherited type.  Using the new keyword adds an additional member to a derived type.

How does the new keyword interact with binding and invocation?  It has no effect at all.  In other words, if you declare a type as 'C' then the member will be bound against 'C'.  The invocation will follow the normal rules, depending on whether it is marked as virtual or not.  The declaration of the inherited type's member is irrelevant to this.  The new keyword plays no part in the binding or invocation logic, it only extends the definition of the derived type with an additional member.

Some conclusions

The following conclusions can be drawn from this discussion:

  1. The new keyword cannot impact the behaviour of an inherited type
    • To change the behaviour, references must use the derived type explicitly
  2. The new keyword cannot prevent access to a member of an inherited type
    • The inherited type can be fully utilised when a reference to a derived type is first cast to the inherited type
  3. The virtual keyword does not impact binding, only invocation
    • All member binding in C# occurs at compile-time
  4. The virtual keyword alone allows manipulation of behaviour by a derived class
    • But it depends on the use of the virtual keyword in the inherited class which may not be within the same domain as the code being written (for example it may be a class from the .NET framework class library)
  5. True encapsulation that can fully adapt the behaviour of a class requires one of the following models
    • The class may be wrapped in an outer class that only exposes a subset of functionality, or else adapts the behaviour of exposed functionality
    • A wholly new class may be developed
  6. Software design is important
    • Some decisions are difficult to change later, for example not using the virtual keyword

References

Versions

  • Microsoft .NET Framework 3.5
  • Microsoft .NET Framework 2.0

Metadata

Tags:

Software Development

Powered by BlogEngine.NET 1.5.0.7
Theme by Interakting

Interakting

A full service digital agency offering online strategy, design and usability, systems integration and online marketing services that deliver real business benefits and ensure your online objectives are met.

Calendar

<<  July 2010  >>
MoTuWeThFrSaSu
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar