Sometimes it is required to add some functionality to existing data structures. The OOP school's way for this is to use inheritance. In situations where we consume interfaces instead of class or structure types we can extend the interface easily. In some languages like Ruby data structures are never sealed. So we can add extra abilities of our objects to the processing workflow of the running engine of the language. However, if the data structures are sealed then there could be no way to do this.
Here we'll see a way to convert two types implicitly that 'simulates' inheritance and when needed our type will be cast internally by the CLR.
When I was studying a few Ruby code snippets I encountered this idea and decided to implementing it in C#. In some scenarios this is very handy. Ruby programmers use this feature in their daily developments. But there is a bit of caution here: this method can be Aggregation or a Composition, and if you are going to extend a complex sealed type in .NET, you must be aware of how it is disposed (Implementing of
is a formal way for doing this). Because the wrapped type does not release it's captured resources, there may be some conflicts in execution path. So the finalization process must takes place properly.
For this we need to construct some facilities in our data structure that enables the CLR to 'infer' our target type from the context.
- Implicit overloaded operators for conversion
Here we'll try to expand string class so this operations will be:
public static implicit operator string(String V)
public static implicit operator String(string n)
return new String(n);
public override bool Equals(object obj)
return this.mval == (string)obj;
public override int GetHashCode()
As you can see by browsing the provided code 'mval' is the internal place for
keeping the object of target type which is 'string'. 'String' is our new type, and 'string' is the .NET standard type for the strings.
In addition we have overloaded two other methods :
GetHashCode. These implementations are needed by the CLR for performing the conversion.
- Providing implementations of necessary unary and binary operations.
Here the only operation that is defined in .NET framework for strings in '+' which makes a new string of it's operands. Of course we can overload other operations in addition to '+' for our purpose.
- Providing implementation of comparison operators.
This is in fact same as previous step and the separation of conceptual paragraph is only an emphasis on it's importance that needs more care.
After this we have done and we have a new type that is equivalent to standard string. We can use it to provide a new type 'email' that is a string with a special format or in any sort of data that will be presented in a formatted string.
Using the code
Let see through the code some practical points. This is
method that performs a simple test :
static void Main (string args)
UpperCaseString ucs = "this Is A teST TeXt.";
Console.WriteLine (ucs << 8);
string newString = ucs << 8 >> 1;
Console.WriteLine ("Press any key to continue ...");
UpperCaseString is an always upper case string class. As you see the instance of
UpperCaseString has been initialized by an ordinary assignment. Then it is consumed by the
WriteLine method of the
Console class to print its value. There is no explicit conversion needed here.
There are new overloaded operators there : '>>' and '<<'. The first one shifts the string n characters to right and '<<' shifts the string n characters to left. Again there no necessary instructions for constructing a new instance of
System.String named here
newString. The result of '>>' and '<<' operations are automatically converted to the proper type (here
This was a little example of using this feature to attach additional functionalities and properties to existing sealed types. You can use the definition of
UpperCaseString as a template for providing your specialized types. In addition you may want to provide some generic tools for performing needed applications.
Points of Interest
It is interesting how can this option affects current implementation scenarios on the .NET plateform. We can name some of them by re-implementing required features in new way. Maybe some sort of parsing texts and file processing or some of GUI data propagation and data gathering and so on. But the more interesting thing would be a case that is nicely fit this and this suited nicely to overcome the problem. Do you know one?
A .NET Developer came from a 'C' and 'C++' background with some experiences in low level programming. In last 2 years I have performed various works in ASP.NET 2.0, .NET compact framework and other .NET things.
I am looking forward for functional programming to be mainstream (Lisp (Scheme), F#, Erlang and Haskell (Clean)). There are two path there I love them both: Lisp path (Power of macros with Scheme, ...) and ML path(Power of ADT and patterns with F#, Haskell, ...) and there are some middle ground too (Nemerle, Scala).