Multiple level base calls

  • Thread starter Thread starter lucas_denoir
  • Start date Start date
Anyway, thanks to all of you for the suggestions. This is as has been
mentioned, not an C# issue per se, but rather an reflection/CLR issue.
Perhaps I'll try in the CLR or the Interop (might surprise you, but
Interop is the closest thing I've come to finding a solution) groups.

For the project, it doesn't quite matter at this point, as a
formalization of the XML was required because of other factors. And
through that the necessary info can be extracted directly from the XML
and no multiple level base calls are necessary. I'm still very curious
of how what I described can be accomplished, but it's not a high
priority anymore.

Thanks again.

--Lucas
 
I can't quite do that as the level at which you choose to deploy is
arbitrary.

Do you mean that the highest level at which you could deploy to the
Compact Framework could be one of the child classes? Well, then I guess
you have to make the "CompactFramework" methods virtual, and trust the
inheriting child classes to override them only when they can, in fact,
deploy to the compact framework.
There can be several components (classes) in the same line of
inheritence that need to be deployed.

OK, now I'm confused again. I thought you said that along a single line
of inheritance, there was some base class that you were trying to find,
which was the one for which you wanted to call ToXml(). Now you're
saying that you may want to call ToXml() for several of the classes up
the hierarchy? Why would you do that when the highest-level one will
include the XML for all of the lower-level ones, and supposedly you're
deploying the most sophisticated control you can to the compact device?
Obviously I don't fully understand what you're trying to achieve. :(
And in addition, it isn't an aesthetically pleasing solution,

Aesthetics is in the eye of the beholder. :) Me, I find messing around
in IL and using Reflection to play tricks aesthetically ugly. :)

I would much prefer to make the situation explicit in my interface:
this class can export to the Compact Framework / this class can't and
instead defers to its base class. In essence I see what you're trying
to do is to load two jobs into one method: Emit XML for the regular
framework and emit XML to deploy to the compact framework, and decide
which to do based on some funky Reflection / IL mashing... or am I not
getting what you're trying to do?
as the XML method would have to be implemented twice in the
deployable class.

Implemented? No, not at all. More like declared. The CompactFramework
versions would never have any more of a body that simply a call to the
corresponding "regular framework" version. Classes that can deploy to
the CF contain an overload. Those that can't, don't. The net effect is
that calling the CompactFramework version of the method will "search up
the hierarchy" until it finds the first class that can deploy to the
framework, and use that class's version of the method, which will
simply call that class's ToXml(). If that's not exactly what you want
to do, then please help me understand better.
Emiting IL is more complicated, but this I can do on my side, sparing

those that write the components to write redundant code.

Nobody has to write redundant code, unless you count three lines of
code in each class that can be deployed to the framework as being
"redundant".

One thing I certainly don't understand is how, if you're going to take
care of this "automagically" under the covers, are you going to figure
out which of the derived classes can be deployed to the framework (and
thus their ToXml() should be used) and which can't (and so you have to
keep searching up the hierarchy)?
 
Nah, base is hard-wired at compile time to the actuall base class where
it is defined (not too strange). For it to work, each child-class would
have to actually implement the base call, resulting in unnecessary and
redundant code that could easily introduce errors throughout the entire
inheritance chain.

Only the classes which override the method would need to call base.Foo.
It's not that hard to do, and it would be very easy to make the top-
level base class keep a flag to check whether or not it had been done
properly (as you could check that *all* methods had been called simply
by knowing whether or not the top method had been called). You could
test the flag after calling the method.
Thanks for your suggestions, they are appreciated, but I'm really not
looking for a workaround to the problem. What I need help with is how
to accomplish it, through reflection, without resorting to IL.

Then choose a different language, basically.
 
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Testing_Samples
{
public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
public Form2()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Name = "Form2";
this.Text = "Form2";
this.Load += new System.EventHandler(this.Form2_Load);

}
private void Form2_Load(object sender, System.EventArgs e)
{
C a = new C();
//Invoking Class C Method
MessageBox.Show(a.PrintMe());
//Casting with Class A Method
MessageBox.Show(((A)a).PrintMe());
}
}
class A
{
public string PrintMe()
{
return "Original A";
}
}

class B : A
{
public string PrintMe()
{
return "Overriden B";
}
}

class C : B
{

public string PrintMe()
{
return "Overriden C";
}
}
}
 
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Testing_Samples
{
public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
public Form2()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Name = "Form2";
this.Text = "Form2";
this.Load += new System.EventHandler(this.Form2_Load);

}
private void Form2_Load(object sender, System.EventArgs e)
{
C a = new C();
//Invoking Class C Method
MessageBox.Show(a.PrintMe());
//Casting with Class A Method
MessageBox.Show(((A)a).PrintMe());
}
}
class A
{
public string PrintMe()
{
return "Original A";
}
}

class B : A
{
public string PrintMe()
{
return "Overriden B";
}
}

class C : B
{

public string PrintMe()
{
return "Overriden C";
}
}
}
 
Hmmm... code with no explanation, and it's code that doesn't even
compile!

I understand the implication: that declaring PrintMe() in classes A, B,
and C will cause "Original A" to print out if you cast a reference of
type "C" to type "A". I assume that you meant to say that:

C a = new C();
//Invoking Class C Method
MessageBox.Show(a.PrintMe());
//Casting with Class A Method
MessageBox.Show(((A)a).PrintMe());

will display two message boxes: one that says, "Overridden C" and the
next that says, "Original A". Unfortunately, if you had tried to
compile this code, you would have found that it wouldn't, because you
must make A's PrintMe "virtual", and specify either "override" or "new"
on B and C's PrintMe.

The behaviour you are claiming will happen only if you declare the
PrintMe methods in B and C to be "new". "new," however, isn't an
override, so you won't get the polymorphic behaviour that the OP wants.

If you were to specify "override," you would get the behaviour that the
OP wants, but both message boxes would display "Overridden C." That, in
a nutshell, was the OP's problem: how to have both message boxes
display "Overridden C," but then go back to call the base method
("Original A") on demand.

Unfortunately, no can do (in C#).
 
Back
Top