Click here to Skip to main content
Click here to Skip to main content

How to expand .NET structs and sealed classes in C#

By , 1 Aug 2006
 

Introduction

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.

Background

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 IDisposable 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.

Overall Process

For this we need to construct some facilities in our data structure that enables the CLR to 'infer' our target type from the context.
  1. 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)
            {
                return V.mval;
            }
            public static implicit operator String(string n)
            {
                return new String(n);
            }<BR>
            //REQUIRED BECAUSE OF CONVERSION OPERATORS
            public override bool Equals(object obj)
            {
                return this.mval == (string)obj;
            }
            public override int GetHashCode()
            {
                return this.mval.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 : Equals and GetHashCode. These implementations are needed by the CLR for performing the conversion.
     
  2. 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.
     
  3. 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 main method that performs a simple test :
static void Main (string[] args)
{
    UpperCaseString ucs = "this Is A teST TeXt.";
    Console.WriteLine (ucs);
    Console.WriteLine (ucs << 8);
    string newString = ucs << 8 >> 1;
    Console.WriteLine (newString);
    //
    Console.WriteLine ("Press any key to continue ...");
    Console.ReadKey ();
}

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 System.String).

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?

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Kaveh Shahbazian
Web Developer
Iran (Islamic Republic Of) Iran (Islamic Republic Of)
Member
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).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Question.NET 2.0?memberhockbock23 Oct '06 - 16:07 
AnswerRe: .NET 2.0?memberKaveh Shahbazian28 Oct '06 - 3:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 1 Aug 2006
Article Copyright 2006 by Kaveh Shahbazian
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid