Hi James:
Interesting question.. I decided to spend 15 minutes to put all this
inheritance stuff straight in my head (and failed :-)
Quote:
> What I'm shooting for is to have a *separate* instance of MyType for each
of
> the inherited types (i.e., one each for Sub1 and Sub2), but still be able
to
> work with them up in Super (i.e., have some base methods which work on
> MyType as well).
another way to put this:
You want to define a base class Super, that has some functions that work on
a static member variable
Then you want to derive a class Sub from it, that does inherit the
functions, but doesn't inherit the static member variable
The functions derived from Super should then work on a static member
variable of Sub instead..
Initialy i thought this was possible (though pretty obscure design wise) by
using the member hiding feature of C#
consider Super:
public class Super
{
protected static string test = "super";
public void DoSomethingNormal()
{
Console.WriteLine(test);
}
public static void DoSomethingSpecific()
{
Console.WriteLine(test);
}
public void Set(string s)
{
test = s;
}
Quote:
}
and class Sub2:
public class Sub2 : Super
{
new protected static string test = "sub2";
public override void DoSomethingSpecific()
{
Console.WriteLine( test + " Written by Sub2" );
}
Quote:
}
Sub2 uses the new keyword to hide the static string test from the Super
class, and this works..
if you call DoSomethingSpecific the output is: "sub2 Written by Sub2"
exactly as wanted (if it would use the test from Super the output would be
"super Written by Sub2")
even if you cast sub2 to a Super, and then call DoSomethingSpecific() it
still outputs the correct text..
The problem starts when you try to the use DoSomethingNormal() function from
the Super class, which is supposed to be our common functionality. nomatter
what you do, it will output "super", since it uses the test from super and
not from sub2.. our exercise
was pointless.
This is the small test program i made, there were some interesting results
:-)
using System;
namespace InheritanceTest
{
class test
{
[STAThread]
static void Main()
{
Super super = new Super();
Sub0 sub0 = new Sub0();
Sub1 sub1 = new Sub1();
Sub2 sub2 = new Sub2();
Sub3 sub3 = new Sub3();
super.DoSomethingSpecific();
super.DoSomethingNormal();
Console.WriteLine();
sub0.DoSomethingNormal();
sub1.DoSomethingNormal();
sub2.DoSomethingNormal();
sub3.DoSomethingNormal();
Console.WriteLine();
sub0.DoSomethingSpecific();
sub1.DoSomethingSpecific();
sub2.DoSomethingSpecific();
sub3.DoSomethingSpecific();
Console.WriteLine();
((Super)sub0).DoSomethingNormal();
((Super)sub1).DoSomethingNormal();
((Super)sub2).DoSomethingNormal();
((Super)sub3).DoSomethingNormal();
Console.WriteLine();
((Super)sub0).DoSomethingSpecific();
((Super)sub1).DoSomethingSpecific();
((Super)sub2).DoSomethingSpecific();
((Super)sub3).DoSomethingSpecific();
Console.WriteLine();
sub2.Set("Sub2 changed");
Console.WriteLine();
sub0.DoSomethingNormal();
sub1.DoSomethingNormal();
sub2.DoSomethingNormal();
sub3.DoSomethingNormal();
Console.WriteLine();
sub0.DoSomethingSpecific();
sub1.DoSomethingSpecific();
sub2.DoSomethingSpecific();
sub3.DoSomethingSpecific();
Console.WriteLine();
((Super)sub0).DoSomethingNormal();
((Super)sub1).DoSomethingNormal();
((Super)sub2).DoSomethingNormal();
((Super)sub3).DoSomethingNormal();
Console.WriteLine();
((Super)sub0).DoSomethingSpecific();
((Super)sub1).DoSomethingSpecific();
((Super)sub2).DoSomethingSpecific();
((Super)sub3).DoSomethingSpecific();
Console.ReadLine();
}
}
public class Super
{
protected static string test = "super";
public void DoSomethingNormal()
{
Console.WriteLine(test);
}
public virtual void DoSomethingSpecific()
{
Console.WriteLine(test);
}
public void Set(string s)
{
test = s;
}
}
public class Sub0 : Super
{
new public void DoSomethingSpecific()
{
Console.WriteLine( test + " Written by Sub0" );
}
}
public class Sub1 : Super
{
public override void DoSomethingSpecific()
{
Console.WriteLine( test + " Written by Sub1" );
}
}
public class Sub2 : Super
{
new protected static string test = "sub2";
public override void DoSomethingSpecific()
{
Console.WriteLine( test + " Written by Sub2" );
}
}
public class Sub3 : Super
{
new protected static string test = "sub3";
new public void DoSomethingSpecific()
{
Console.WriteLine( test + " Written by Sub3" );
}
}
Quote:
}
Actually, now i think about it, there is some sort of way that does not
require code duplication for the common functionality, though it it isn't
fully transparant..
in Super:
1) create a virtual get and set function for your static variable
2) implement all common functionality using those get and set methods
in a Sub
1) define your own class specific static variable
2) override the acces methods to return that variable instead..
this is some example code, it works in all cases i could think of..
using System;
namespace InheritanceTest
{
class test
{
[STAThread]
static void Main()
{
Super super = new Super();
Sub1 sub1 = new Sub1();
Sub1 sub1a = new Sub1();
Sub2 sub2 = new Sub2();
Sub2 sub2a = new Sub2();
super.DoCommonStuff();
sub1.DoCommonStuff();
sub2.DoCommonStuff();
Console.WriteLine();
sub1.SetStaticMember("sub1 changed");
super.DoCommonStuff();
sub1.DoCommonStuff();
sub1a.DoCommonStuff();
sub2a.DoCommonStuff();
sub2.DoCommonStuff();
Console.WriteLine();
((Super)sub1).DoCommonStuff();
((Super)sub2).DoCommonStuff();
Console.ReadLine();
}
}
public class Super
{
private static string test = "super";
protected virtual string getValue()
{
return test;
}
protected virtual void setValue(string s)
{
test = s;
}
// common functionality
public void DoCommonStuff()
{
Console.WriteLine(getValue() + " Common");
}
public void SetStaticMember(string s)
{
setValue(s);
}
}
public class Sub1 : Super
{
private static string test = "sub1";
protected override string getValue()
{
return test;
}
protected override void setValue(string s)
{
test = s;
}
}
public class Sub2 : Super
{
private static string test = "sub2";
protected override string getValue()
{
return test;
}
protected override void setValue(string s)
{
test = s;
}
}
Quote:
}
ah well, time for bed :-)
Willem