Click here to Skip to main content
Email Password   helpLost your password?

Introduction

There are situations where multiple inheritance is the best (if not the only) choice when designing a certain model for our program or project. C# unfortunately does not support multiple inheritance and so we must look for ways to adapt our design to make possible its implementation. But C# does offer resources and tricks that can be used to simulate multiple inheritance without radically redesigning our class model, with only adding several auxiliary methods and classes and taking one or two precautions while coding them. I propose a design pattern that lets us simulate multiple inheritance in a C# program in a way that produces classes that behave almost like they were really extended from two or more parent classes. We will face classical multiple inheritance problems too and will see how to address them.

Background

Most recent languages like C#, Java, Delphi, have simple inheritance. They don't have multiple inheritance because their designers had to choose between have it in and have all the problems it comes with, or get it out of the language putting away all those problems, and introduce a versatile and less problematic substitute like interfaces and interface inheritance. Multiple inheritance has multiple problems that we will discuss later. But those problems are quite pathological and do not arise in any program in which multiple inheritance could be useful or could be the most appropriate design.

There are traditional ways to emulate multiple inheritance with interface inheritance with more or less success. Let's suppose we have two classes, A and B, and we want C to inherit from both of them.

class A
{
    m1();
}

class B
{
    m2();
}

class C : A, B
{
    m1();
    m2();
}

That code is impossible in C#. The following is the classical workaround to deal with this:

class A
{
    m1();
}

interface IB
{
    m2();
}

class B : IB
{
    m2();
}

class C : A, IB
{
    B BObject;
    m1();
    m2() { BObject.m2(); }
}

In this code, we make class B to implement a new interface named IB that has identical methods as those of B. Then class C inherits from A and IB, and uses an internal B object that replicates B's m2 method implementation. So C.m2 in fact calls its BObject.m2 method. Then we can say C now has A's implementation of m1() and B's implementation of m2(). And we can use C object wherever we could use A objects or IB objects.

But this solution has several problems. One of them is the fact that we can't use C objects where explicitly B objects are expected, but only where IB objects are. So maybe we will have to change all the other code in the project, replacing references to B objects with references to IB objects. That will not be a big problem if we are designing the model and can take such decisions. But if the project is dependant on third party code or the standard library (the Framework) then we will be unable to make those modifications. Even more important, if class B is not ours, but it is from the standard library or from third party code, we can't make it implement our IB interface. We can't touch it.

The simulated multiple inheritance pattern for C#

We have seen that we cannot simulate multiple inheritance completely using only interfaces and simple inheritance. We need something more, and C# happens to have that. Let's see.

We have these objectives:

Here is the basic idea:

We will create two auxiliary classes, Aaux and Baux that inherit from A and B respectively.

class A
{
    m1();
}

class B
{
    m2();
}

class Aaux : A
{
    m1();
}

class Baux : B
{
    m2();    
}

Our new class C won't inherit from A or B but have the same methods of both of them. Besides, it will contain two objects: one of type Aaux and the other of type Baux. We will call them C.APart and C.BPart respectively. C will use their implementations of m1 and m2 instead of rewriting them.

class C
{
    Aaux APart;
    Baux BPart;
    
    m1()
    {
        APart.m1();
    }
    m2()
    {
        BPart.m2();
    }
}

So every C object has a pair of A and B objects inside. Let's make those objects know who is containing them by adding a reference to the C object that contains them. We will modify classes Aaux and Baux for this purpose:

class Aaux : A
{
    C CPart;
    
    m1();
}

class Baux : B
{
    C CPart;
    
    m2();
}

And finally we arrive at the final trick. We will redefine the implicit casting operator for class C, so:

Again, we will redefine the implicit casting operator for class Aaux so whenever a C object is expected and an Aaux object is found, Aaux.CPart is returned. Identically, we will redefine the implicit casting operator for class Baux so whenever a C object is expected and a Baux object is found, Baux.CPart is returned.

This is the final look:

class Aaux : A
{
    C CPart;
    
    m1();
    
    static implicit operator C(Aaux a)
    {
        return a.CPart;
    }
}

class Baux : B
{
    C CPart;
    
    m2();

    static implicit operator C(Baux b)
    {
        return b.CPart;
    }
}

class C
{
    Aaux APart;
    Baux BPart;
    
    m1()
    {
        APart.m1();
    }
    m2()
    {
        BPart.m2();
    }

    static implicit operator A(C c)
    {
        return c.APart;
    }
    static implicit operator B(C c)
    {
        return c.BPart;
    }
}

Now given that code, we can use C objects wherever an A or B object is expected, in addition to where a C object is expected. The only cost has been adding two extra classes and requiring the parent classes not to expose public fields.

However, there is another step we can take that will allow us to reduce in on the number of extra classes required and will let one of the parent classes have public fields. In fact, the class diagram will be even simpler.

We only have to make C inherit directly from A, the class which exposes public fields.

Of course, properties are fully compatible with this pattern, since they behave like methods. So parent classes may have as many public properties as they wish.

Using the code

Let's see an example. We are a computer dealer that buys computer hardware from major vendors and sells it to end users. However, we often get out of stock and we avoid losing customers by buying from rival computer shops and re-selling to our customers. We are not the only ones with that policy, so other shops often purchase our goods for selling them later. Our program has two arrays - in one of them we keep all our vendors, and in the other we keep all our customers. Rival shops are both vendors and customers. This would be the idea:

class Vendor
{...}
class Customer
{...}
class Shop : Vendor, Customer
{...}

And this could be the final code (it's available in the download):

    /// <summary>

    /// A computer manufacturer. They resupply us.

    /// </summary>

    public class Vendor
    {
        string id;
        public string VendorId
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }

        public Vendor(string vendorId)
        {
            id = vendorId;
        }

        public virtual void AskForRessuply()
        {
            Console.WriteLine("Please ressuply me, vendor "+id+".");
        }
    }

    /// <summary>

    /// A customer. We send them their purchased goods.

    /// </summary>

    public class Customer
    {
        string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public Customer(string customerName)
        {
            name = customerName;
        }

        public virtual void SendOrder()
        {
            Console.WriteLine("Dear "+name+": We are sending your goods.");
        }
    }


    /// <summary>

    /// The auxiliary class that redefines Customer.

    /// </summary>

    internal class CustomerAux : Customer
    {
        // <--- It has a link to the Shop object that contains it.

        internal Shop shopPart;        

        internal CustomerAux(string customerName) : base (customerName)
        {
        }

        // We declare the implicit casting operator for returning 

        // shopPart when a Shop object is expected.

        static public implicit operator Shop(CustomerAux c)
        {
            return c.shopPart;
        }
    }


    /// <summary>

    /// We consider a shop like a Vendor and a Customer, 

    /// for we both ask them to resupply us,

    /// or they purchase our goods.

    /// </summary>

    public class Shop : Vendor        // <-- It inheirs only from Vendor...

    {
        CustomerAux customerPart;    // ...but has a CustomerAux object inside.


        // Shops have an address in addition to the vendor id 

        // and the customer name inherited from Vendor and Customer.

        string address;                
        public string Address
        {
            get
            {
                return address;
            }
            set
            {
                address = value;
            }
        }
        // Here we are 'redirecting' property Name to the customerPart object.

        public string Name        
        {
            get
            {
                return customerPart.Name;
            }
            set
            {
                customerPart.Name = value;
            }
        }

        // The Shop constructor. 

        public Shop(string vendorId, string customerName, string shopAddress) : 
                                                                  base (vendorId)
        {
            // We create and bind the CustomerAux object to this one.

            customerPart = new CustomerAux(customerName);    
            customerPart.shopPart = this;

            address = shopAddress;
        }

        // Here we are redirecting Customer.SendOrder to the customerPart object.

        public virtual void SendOrder()
        {
            customerPart.SendOrder();
        }

        // We redefine the implicit casting operator for returning 

        // customerPart when a Customer object is expected.

        static public implicit operator Customer(Shop s)
        {
            return s.customerPart;
        }

    }

    // An example of use of the Vendor, Customer and Shop classes.

    class EntryPoint
    {
        static void Main(string[] args)
        {
            Vendor ibm = new Vendor("32FK-IBM");
            Vendor hp = new Vendor("1138-HP");
            Customer mrSimpson = new Customer("Mr. Simpson");
            Customer mrGates = new Customer("Mr. Gates");
            Shop joys = 
              new Shop("1979-JCS", "Joy's Computer Shop", "123, Fake St.");

            Vendor[] vendors = {ibm, hp, joys};
            foreach(Vendor ven in vendors)
                ven.AskForRessuply();
            
            Customer[] customers = {mrSimpson, mrGates, joys};
            foreach(Customer cus in customers)
                cus.SendOrder();
            Console.ReadLine();            
        }
    }

Points of interest - classical problems

One of the most important problems of multiple inheritance is caused by this situation:

Class A has the m1() method. The [ImpA] means that method m1 has been implemented in A. Classes B and C inherit from A, and both of them redefine method m1. So class B has its own implementation of m1, denoted by [ImpB], and class C has its own implementation of m1 too, denoted by [ImpC].

Now class D inherits from B and C. The problem is... what implementation of m1 is used while running this code?

D d = new D();
d.m1();

...this code?

B d = new D();
d.m1();

...and this code?

C d = new D();
d.m1();

Languages and compilers supporting multiple inheritance solve this in one way or the other. But this makes compiling, debugging and understanding the code more difficult. Often the version of the implementation of m1 to be run is nearly unpredictable.

However, this pattern solves to certain degree that problem, because we can choose what implementation will be run. Assuming our D class uses our pattern for simulating multiple inheritance, there will be five different situations:

Last comment

Multiple inheritance was not included in C# for important reasons. However, I sometimes miss it and that is the reason why I proposed this pattern. I think it may be useful for those who find more advantages in its application than disadvantages. I'd like to see your comments on it, telling problems I didn't see and advices for enhancement.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralErrors
Rudedog2
6:43 27 May '09  
This idea is clever and I give it due credit. But, the implementation and posted samples are not valid C# code. So I will assume that it is psuedo-code. But given that, midway through the author claims success without declaring public fields and methods.

Not possible. Any operator must be static and public. The method members of the #aux classes are not accessible unless they too have accessiblility raised from private. I just do not understand how those claims could be made and no one noticed these issues.

Rudedog2
GeneralRe: Errors
David Esparza-Guerrero
9:33 27 May '09  
I think I don't understand what you say there.
The code in the last example of Vendor, Shops and Orders is valid C# and it works as intended (although I wrote it 4 years ago and don't have it fresh in my memory.)
Which methods are not public that should be? All operators are declared static public as you say.
Can you please explain your objection?
GeneralSee Eiffel for a better paradigm
MurphTheGreat
19:37 4 Jul '07  
The Eiffel programming language has a .NET based implementation that offers multiple inheritance. However, for each class it creates a matching interface and then uses type renaming to change all references to the concrete type in variable declarations, arguments, etc. to references to the interface. When multiple classes are inherited, I believe it implements the interface and then copies the code from the concrete class that the interface defines. This is certainly less difficult when you're writing your own compiler, but something similar might be the better way to do it.
GeneralI said it once and I will say it again
icestatue
2:47 14 Feb '06  
This is not inheritance by any means. Again people are lured into false ideas about C# supporting multiple inheritnce or even a way of truely synthisizing. Most authors on this topic try to fool people using fancy notation to try to decentralize all the properties True inheritnce has. In order to fit the bill of inheritnce you need the following to say the least
1) Access to protected members.
2) The ability to override virtual functions.
3) Down casting support.
4) Maybe more behaviors I have not listed.

These behaviors must be true for all base classes not just a select few to be considered multiple inheritnce. As well as, you might not beable to prepare the base classes to create a multiple inheritnce like behavior because both base classes maybe third party classes you cant access. Most people don't actually analyze the interactions between 2 simple models and attempt to see how these simple interactions work before they build more off of this base. This leads to faulty design work.

nothing
GeneralGood Idea. But have to be careful
Salil Pitkar
8:32 3 Dec '05  
Excellent article.

This works within the same namespace (and or assembly). But if the subclsses are in a different namespace, it could cause circular dependency.

Care should be taken when writing multi-threaded applications involving such a class structure.
GeneralProblem...
fcuesta
5:00 18 Oct '05  
Consider the following code in your sample:

ArrayList arr = new ArrayList();
arr.Add(mrSimpson);
arr.Add(mrGates);
arr.Add(joys);
foreach(Customer cus in arr)
cus.SendOrder();

You will get an exception, because “joys” is not really a Customer.
This makes your pattern useless in the most common scenarios.

Good work, anyway.
GeneralRe: Problem...
David Esparza-Guerrero
9:22 3 Dec '05  
Right. You cannot cast from object directly to Customer when playing with a Shop object like joys. That's cause this is not real multiple inheritance. Just a workaround to simulate this that works only if we take care and provide ways to make it work. So, of course, this simulation is not totally transparent in any way.

Just consider changing
ArrayList arr = new ArrayList();
with
ArrayList arr = new ArrayList();

or use an array:
Customer[] arr = {mrSimpson, mrGates, joys};
or
Customer[] arr = new Customer[3];
arr[0] = mrSimpson;
arr[1] = mrGates;
arr[2] = joys;
...for example.
GeneralRe: Problem...
tekcode
8:53 29 Sep '09  
Also changing the ArrayList to a strongly typed List<> object works fine.

List arr = new List();

arr.Add(mrSimpson);
arr.Add(mrGates);
arr.Add(joys);

foreach (Customer c in arr)
Console.WriteLine(c.Name);


This can allow you to have a list that can scale instead of using an array which needs a predefined size you may not always know, and maintain the ability to cast to the object you need at the same time.
QuestionMultiple inheritance with built in classes
Snews
2:22 10 Oct '05  
Hi, thanks for a great article.

But I have one question.
I'm trying to make an implementation of the Control and all the Windows Forms controls, my problem is this:

I need to have a properti defined for all the controls that's goint to hold some data for validation of the control. I also need to be able to cast this Form classes into it's own Control base class, but here's my real problem, I need to cast ths base Control class into my own controll base class.

Hm, simplifying with some code

public interface IOwnControlBase
{
string ValidationKey
{ get; set; }
/// ets...
}

public class OwnControlBaseClass : Control, IOwnControlBase
{
/// Implement the interface
}

public class OwnButtonClass : Button, IOwnControlBase
{
/// Here I would like to be able to implement the OwnControlClass Sniff
}

Higher up in the application I want to iterate through the Controls collection for a Form or another control and cast the Control into my own OwnControlBase class to get the hold of the ValidationKey value

Do you have any good suggestions for this, or should I re-concider my approatch?

Tanks in advance
AnswerRe: Multiple inheritance with built in classes
David Esparza-Guerrero
6:18 10 Oct '05  
Well. I'm not sure if I've understood you. Basically, you want to have the ValidationKey property in every type of control, yet being able to use those controls just like normal ones. Am I wrong?

Snews wrote:
Higher up in the application I want to iterate through the Controls collection for a Form or another control and cast the Control into my own OwnControlBase class to get the hold of the ValidationKey value

Click here to see this image.

With that design you could do this in the application...
foreach (IOwnControlBase control in myWindow.Controls)
{
DoSomething(control.ValidationKey);
}

...if you are sure all controls in your window form are of your new OwnWhatever type. If you aren't sure, use this instead...
foreach (Control control in myWindow.Controls)
{
if( !(control is IOwnBaseControl) )
continue;
IOwnControlBase ocb = control as IOwnBaseControl;
DoSomething(ocb.ValidationKey);
}


I hope that was what you meant. If not, tell me, please.
GeneralExcellent
Nigel Shaw
10:16 3 May '05  
An excellent article! Thanks!

Nigel
GeneralWhy Baux?
Paolo Marty
5:16 15 Apr '05  

Hi David, I can’t see the reason to implement the implicit cast in class Baux (CustomerAux). After all, you should not be allowed to turn a base B object into a derived C object. Should you? So, it drops the need for class Baux at all. You could have included directly a B object inside C. Is there something that I’m missing?

Bye, Paolo

GeneralRe: Why Baux?
David Esparza-Guerrero
8:14 15 Apr '05  
Yes, you are missing something. The main reason of this pattern, in fact.
With multiple inheritace, a C object must be able to be referenced from a C-type variable, an A-type variable, and a B-type variable.
C var1 = new C();
A var2 = var1;
B var3 = var1;


The presence of the implicit operators in the pattern is not for letting you turn a B object in a C object. They are there for enabling a C-type variable to reference a Baux object, and for a B-type variable to reference a C object. The implicit operators don't 'convert' a Baux object in a C object, but they merely return the C object linked to the Baux object so that the C-type variable can reference it, and vice versa.
And they are 'implicit', not 'explicit', for making all this invisible to the programmer that is using the C object.

Look at the basic pattern, the one with the Aaux and Baux classes.
You can imagine this as C object having three faces: a C face, an A face, and B face. When a C-type variable wants to reference it, it shows its C face. When an A-type variable wants to reference it, then it changes to its A-face, etc. Theese 'changings of face' is done by the implicit operators. Back to the example above:
C var1 = new C(); /* The new C object is created. C-type var1 is referencing its C face. */
/* var2 is A-type and wants to reference the object var1 is referencing.
Then quickly the implicit operator in class C makes var2 reference the A face
of the object referenced by var1. */

A var2 = var1;
/* var3 also wants to reference the object referenced by var1. The other implicit operator in class C makes var3 reference the B face of the object. */
B var3 = var1;

B[] array = { new B(), new C(), new B()}; /* Here a new C object is showing its B face to the array in order to be in there (thanks to the implicit operator in C class). */
C var4 = (C)array[1]; /* Here we recover the C object from the array. The object that was showing its B face now shows it C face to var4 (thanks to the implicit operator in class B) */

So yo can see Aaux and Baux classes as a way of giving class C an A face and a B face. And the implicit operators are there for showing the correct face when variables of different type want to reference the 'multi-faced' object.

I hope I have not made it more confusing than before. :P
GeneralRe: Why Baux?
Paolo Marty
7:20 18 Apr '05  
No, no, it’s clear. So, the implicit cast in Baux – and the Baux class itself – is required in order to do the dynamic cast from a base reference (hopefully referencing a derived object) to a derived reference, what is normally allowed using inheritance - both multiple and single. (Maybe, but this is another story, it is arguable if this feature is really useful - after all you omitted it from your article's example). In your last example, only the last line of code
C var4 = (C)array[1];
requires the cast implementation in Baux to be compiled. Right?

Thank you for the explanation,
Paolo

GeneralRe: Why Baux?
David Esparza-Guerrero
9:10 18 Apr '05  
Yes, only the last line requires casting from Baux to C.

And yes, my article's example is bad Roll eyes. I think I have to look for a better example.
But I don't really undesrtand when you say that the usefullness of casting from a base reference is argueable OMG. Let's see another example.

Imagine we want a class that represents a document that can be filled up just like any TextWriter in the framework. But it has all functionality Word documents have.
class CoolDocument: TextWriter, WordDoc
{ ... }

Besides, we want to use the SpellCorrector class for Word documents we already have for correcting the spelling in WordDoc objects. The SpellCorrector class is similar to

class SpellCorrector
{
SpellCorrector(WordDoc sourcedoc);
WordDoc GetCorrected();
}

that last method returns a clone of our source doc, but with all spelling corrected.
Then let's see this code
CoolDocument mydoc = new CoolDocument();
SpellCorrector sc = new SpellCorrector(mydoc);
CoolDocument mycorrecteddoc = (CoolDocument)sc.GetCorrected();

At the last line of that code the we are casting from a corrected WordDocAux object, returning its CoolDocument part for mycorrecteddoc variable.
We make the casting because we know we are to get a CoolDocument object. It would raise an exception if it was a WordDoc.
GeneralRe: Why Baux?
Paolo Martinoli
6:55 20 Apr '05  
Ok, good! I forgot to say that I find your idea very interesting, both in practice and as a cue for study.

Paolo


It was an adult world, we made mistakes as professionals.
GeneralRe: Why Baux?
David Esparza-Guerrero
10:09 20 Apr '05  
Thank you. Smile
GeneralYou still have to write pass throughts for all methods.
Dr.Drew
8:54 13 Apr '05  
It looks like class C still has to implement pass-throughs for all methods implemented on classes A and B.

Am I understanding this correctly?
GeneralRe: You still have to write pass throughts for all methods.
David Esparza-Guerrero
10:30 13 Apr '05  
If we use the version where only an auxiliary class is needed, then class C needs a redirecting method for each of B's methods. But only needs that if C is interested in providing all those methods.

For example, the framework provides two classes InputStream and OutputStream, and I want to create a class File that inheirs from them both. I am only interested on InputStream.Read() method and OutputStream.Write() method, but not on the other one hundred methods those classes also have. Then our File class only has to have File.Read() and File.Write() methods that only redirect to the InputStream and OutputStream ones. All others can be ignored. We can say we are hiding them.
However, it will still work well when our File object is referenced as an InputStream or an OutputStream and any of those other methods is called, because our auxiliary object would accept that call, for it really inheirs from InputStream or OutputStream and has all methods its parent class has.
GeneralRe: You still have to write pass throughts for all methods.
loqui
23:30 21 Jul '05  
I think passthrough methods are probably my biggest headache in C#. I find myself constantly typing huge blocks of redundant code. In fact, DeveloperExpress has created an entire product "CodeRush" which enables the programmer to more efficiently manipulate the huge blocks of redundant code.

This really seems like a design problem with the C# language. Multiple inheritance? Generics? Mixins? There has to be some kind of language feature that can restore the conciseness of C++.

-Loqui
GeneralRe: You still have to write pass throughts for all methods.
David Esparza-Guerrero
2:00 22 Jul '05  
¿Can you post an example why you need to rewrite such a lot of redundant code?
That would make clearer why you think C++ is more concise than C#.
GeneralRe: You still have to write pass throughts for all methods.
loqui
7:58 22 Jul '05  
Multiple inheritance is a good example -- look at how much code it took you to represent the simple concept of "class C : A, B". In particular, your classes only had a couple members, whereas a realistic example would involve 20-30 members that all need to be rerouted. I encounter this all the time, e.g. whenever a class needs to inherit from both "Control" and some other class.

Another problem is the lack of support for optional parameters, requiring lots of redundant overloads -- e.g. Microsoft's MessageBox.Show() has 12 versions! (Also, this prevents the object browser from showing you what the parameter defaults will be.)

C# also lacks support for indexed properties, requiring entire "indexer" classes to be defined for each property. (See http://tinyurl.com/7rpzf for an example.)

Container classes are responsible for an entire category of redundant code, but fortunately this will be solved by generics when VS2005 is released. And lastly, C++ supports a macro preprocessor which (say what you will) can tremendously reduce the typing required for repetitive patterns. Obviously the C++ preprocessor is not ideal, but surely a compromise is possible!

I have a theory that Micrsoft's marketing dept met secretly and drew up a big list of all the best language features. Then they intentionally deleted 25% from VB, and a different 25% from C#, to ensure that neither would be obviously superior. Finally, they deleted another 25% and marked it "reasons to upgrade". Smile


Cheers,
-Loqui
GeneralRe: You still have to write pass throughts for all methods.
David Esparza-Guerrero
9:45 22 Jul '05  
Oh, OK. Yes, I know C++ has more features than C#. Some think it has too many.
Fortunately C# is an evolving language and maybe we'll see several of those missing features in future versions.

GeneralRe: You still have to write pass throughts for all methods.
Sagenth
5:41 30 Mar '08  
I have got to say I don't think kbhit, or getch... are things to be considered overkill.. Really annoying to work around where they would have been used, as they are just efficient and logical to use. readkey or readline are not *shiver*
So I am guessing from the last reply, there isn't a way to just straight out inherit those methods.. I don't want to go about writing stupid little gates to my real methods, waste of life. I've got self made classes efficiently made, I don't have any reason to exclude any of their functions.
:( another year of C# left

btw I actually feel to the contrary, that c# has more features.. the lists and lists of tools available seems too great, whereas C++ I have always made my own tools to use

So anyways, I wouldn't be able to just inherit my interfaces, and through something else inherit the definitions to the interfaces through something else.. and not have to gate into them..? It would really make things go a lot better if I don't spend all my assignment time coding redirects. Code being used inside a class which already contains, to some extent, the code inheritted from other objects or classes or what have you, or at least that is the goal here.
I would hope that is achievable with C#
GeneralRe: You still have to write pass throughts for all methods.
Dmitri Nesteruk
5:43 2 Nov '08  
Umm, I think you are meant to generate them, not to type them in. For example, if you are implementing the Decorator pattern over a class, you'd expect to simply generate pass-through methods/props for the decorated object.

Oh, and mixins are possible in C#, but they appear different from those in C++. Still, they can be done, and yield interesting results.


Last Updated 9 Apr 2005 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010