Calling base implementation from base class?

  • Thread starter Thread starter Joel
  • Start date Start date
J

Joel

Is there a way to call a base class implementation of a protected method
when Here's the scenario:

class MyApp
{
public static Main()
{
D obj=new D();

obj.Method1();
}
}


class B
{
protected void Method1()
{
}

protected void Method2()
{
//I want to call B's implementation of Method1 even though I'm
running as D's implementation of Method2;
//conceptually I want to do: this.base.Method1();
}
}

class D : B
{
override protected void Method1()
{
Method2();
}
}



Is this doable?

TIA

</joel>
 
Depends much on what interface you want to expose. Did you try running your
code? It would not run because B.Method1 is protected. So the first thing
you need to do is make it public. But in that case, you would be changing
the signature of A.Method1 which you are overriding and that is not allowed.
The following will work, but may not exactly meet your requirements.

class MyApp

{

public static void Main()

{

D d = new D();

d.Method2();

}

}



class B

{

protected virtual void Method1()

{ Console.WriteLine("Inside B.Method1()"); }

}

class D : B

{

public void Method2()

{ base.Method1(); }

}
 
Sorry, I pulled that sample out of thin air without testing it. Here's
working code to illustrate the problem:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
Method1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}

This results in an endless loop of :

Derived.Method1
Base.Method2
Derived.Method1
Base.Method2

because the call to Method1() in Base calls Derived's implementation. What I
want is for the Method1 invocation in Base to call its (Base's)
implementation of Method1. The desired output would be:

Derived.Method1
Base.Method2
Base.Method1

Sorry I wasn't clearer before.
 
What your intention is seems to be a little clearer.
However, it also suggests a deeper design problem. If
details about your actual application situation were
known, an alternative workable design could be suggested.
In the absence of that, the following might help:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1() // Does
this need to be public?
{
Console.WriteLine("Inside
Base.Method1()");
Method3();
}

protected void Method2()
{
Console.WriteLine("Inside
Base.Method2()");
Method3();
}

private void Method3()
{
Console.WriteLine("Inside
Base.Method3()");
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Inside
Derived.Method1()");
base.Method2();
}
}
}

The essence of what is different in this code is that
whatever code in Base that must be executed when
Derived.Method1() is called is moved to Base.Method3().

-----Original Message-----
Sorry, I pulled that sample out of thin air without testing it. Here's
working code to illustrate the problem:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
Method1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}

This results in an endless loop of :

Derived.Method1
Base.Method2
Derived.Method1
Base.Method2

because the call to Method1() in Base calls Derived's implementation. What I
want is for the Method1 invocation in Base to call its (Base's)
implementation of Method1. The desired output would be:

Derived.Method1
Base.Method2
Base.Method1

Sorry I wasn't clearer before.

eSapient said:
Depends much on what interface you want to expose. Did
you try running
your
code? It would not run because B.Method1 is protected. So the first thing
you need to do is make it public. But in that case, you would be changing
the signature of A.Method1 which you are overriding
and that is not
allowed.
The following will work, but may not exactly meet your requirements.

class MyApp

{

public static void Main()

{

D d = new D();

d.Method2();

}

}



class B

{

protected virtual void Method1()

{ Console.WriteLine("Inside B.Method1()"); }

}

class D : B

{

public void Method2()

{ base.Method1(); }

}


.
 
Wouldn't a cast like

((Base)this).Method1 () ;

in your Method2 solve your problem?

/LM

Joel said:
Sorry, I pulled that sample out of thin air without testing it. Here's
working code to illustrate the problem:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
Method1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}

This results in an endless loop of :

Derived.Method1
Base.Method2
Derived.Method1
Base.Method2

because the call to Method1() in Base calls Derived's implementation. What I
want is for the Method1 invocation in Base to call its (Base's)
implementation of Method1. The desired output would be:

Derived.Method1
Base.Method2
Base.Method1

Sorry I wasn't clearer before.

eSapient said:
Depends much on what interface you want to expose. Did you try running your
code? It would not run because B.Method1 is protected. So the first thing
you need to do is make it public. But in that case, you would be changing
the signature of A.Method1 which you are overriding and that is not allowed.
The following will work, but may not exactly meet your requirements.

class MyApp

{

public static void Main()

{

D d = new D();

d.Method2();

}

}



class B

{

protected virtual void Method1()

{ Console.WriteLine("Inside B.Method1()"); }

}

class D : B

{

public void Method2()

{ base.Method1(); }

}
 
Luc E. Mistiaen said:
Wouldn't a cast like

((Base)this).Method1 () ;

in your Method2 solve your problem?

No, because it would still be called polymorphically.
 
That's the first thing I tried and it doesn't work.

Check out
http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_10_5_4.asp.
Specifically the paragraph right after the first example. It explicity
states:

Had the invocation in B been written ((A)this).PrintFields(), it would
recursively invoke the PrintFields method declared in B, not the one
declared in A, since PrintFields is virtual and the run-time type of
((A)this) is B.

I worked around my immediate problem but now I'm just academically curious.
It doesn't strike me that there's anything "illegal" about doing what I
want, it just seems like there is no syntax for it.

Anyone from MS want to pitch in?

</joel>

Luc E. Mistiaen said:
Wouldn't a cast like

((Base)this).Method1 () ;

in your Method2 solve your problem?

/LM

Joel said:
Sorry, I pulled that sample out of thin air without testing it. Here's
working code to illustrate the problem:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
Method1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}

This results in an endless loop of :

Derived.Method1
Base.Method2
Derived.Method1
Base.Method2

because the call to Method1() in Base calls Derived's implementation.
What
I
want is for the Method1 invocation in Base to call its (Base's)
implementation of Method1. The desired output would be:

Derived.Method1
Base.Method2
Base.Method1

Sorry I wasn't clearer before.
 
Jon,

Any ideas on how this can be accomplished? If it's not doable I wonder why?
It doesn't seem to break any OO rules.

</joel>
 
Joel said:
Any ideas on how this can be accomplished? If it's not doable I wonder why?
It doesn't seem to break any OO rules.

I'd suggest having either an abstract or empty method which is virtual,
and make every method you want to call from your code non-virtual. It's
fairly common to have a non-virtual method which does something
(preparation, for example), calls a virtual or abstract method, and
then does something else (clean-up or whatever). The non-virtual method
is often public, with the abstract/virtual method being just protected.
 
It actually is possible at the IL level - using the CALL instruction versus
the CALLVIRT. I am not sure why there doesn't seem to be a C# syntax for it.
In my situation, I created a utility class in IL that I then merged in with
my assembly (multi-module assembly). Unfortunately, VS.NET doesn't give you
much help in such a build - makefiles are much easier.

Joel said:
That's the first thing I tried and it doesn't work.

Check out
http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_10_5_4.asp.
Specifically the paragraph right after the first example. It explicity
states:

Had the invocation in B been written ((A)this).PrintFields(), it would
recursively invoke the PrintFields method declared in B, not the one
declared in A, since PrintFields is virtual and the run-time type of
((A)this) is B.

I worked around my immediate problem but now I'm just academically curious.
It doesn't strike me that there's anything "illegal" about doing what I
want, it just seems like there is no syntax for it.

Anyone from MS want to pitch in?

</joel>

Luc E. Mistiaen said:
Wouldn't a cast like

((Base)this).Method1 () ;

in your Method2 solve your problem?

/LM

Joel said:
Sorry, I pulled that sample out of thin air without testing it. Here's
working code to illustrate the problem:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
Method1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}

This results in an endless loop of :

Derived.Method1
Base.Method2
Derived.Method1
Base.Method2

because the call to Method1() in Base calls Derived's implementation.
What
I
want is for the Method1 invocation in Base to call its (Base's)
implementation of Method1. The desired output would be:

Derived.Method1
Base.Method2
Base.Method1

Sorry I wasn't clearer before.

Depends much on what interface you want to expose. Did you try running
your
code? It would not run because B.Method1 is protected. So the first thing
you need to do is make it public. But in that case, you would be changing
the signature of A.Method1 which you are overriding and that is not
allowed.
The following will work, but may not exactly meet your requirements.

class MyApp

{

public static void Main()

{

D d = new D();

d.Method2();

}

}



class B

{

protected virtual void Method1()

{ Console.WriteLine("Inside B.Method1()"); }

}

class D : B

{

public void Method2()

{ base.Method1(); }

}


Is there a way to call a base class implementation of a protected method
when Here's the scenario:

class MyApp
{
public static Main()
{
D obj=new D();

obj.Method1();
}
}


class B
{
protected void Method1()
{
}

protected void Method2()
{
//I want to call B's implementation of Method1 even though I'm
running as D's implementation of Method2;
//conceptually I want to do: this.base.Method1();
}
}

class D : B
{
override protected void Method1()
{
Method2();
}
}



Is this doable?

TIA

</joel>
 
The best I can think of then is:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
private void BaseMethod1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method1()
{
BaseMethod1();
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
BaseMethod1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}
 
I guess I'll have to start learning IL :-)

Thanks for the info. I hope MS adds this to C# soon. It doesn't come up
often but when you need it, you end up with a messy work-around.

Thanks again.

</joel>


Brian Tyler said:
It actually is possible at the IL level - using the CALL instruction versus
the CALLVIRT. I am not sure why there doesn't seem to be a C# syntax for it.
In my situation, I created a utility class in IL that I then merged in with
my assembly (multi-module assembly). Unfortunately, VS.NET doesn't give you
much help in such a build - makefiles are much easier.

Joel said:
That's the first thing I tried and it doesn't work.

Check out
http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_10_5_4.asp.
Specifically the paragraph right after the first example. It explicity
states:

Had the invocation in B been written ((A)this).PrintFields(), it would
recursively invoke the PrintFields method declared in B, not the one
declared in A, since PrintFields is virtual and the run-time type of
((A)this) is B.

I worked around my immediate problem but now I'm just academically curious.
It doesn't strike me that there's anything "illegal" about doing what I
want, it just seems like there is no syntax for it.

Anyone from MS want to pitch in?

</joel>

Luc E. Mistiaen said:
Wouldn't a cast like

((Base)this).Method1 () ;

in your Method2 solve your problem?

/LM

Sorry, I pulled that sample out of thin air without testing it. Here's
working code to illustrate the problem:

using System;

namespace ConsoleApplication4
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Derived d=new Derived();
d.Method1();
}
}

class Base
{
public virtual void Method1()
{
Console.WriteLine("Base.Method1");
}

public virtual void Method2()
{
Console.WriteLine("Base.Method2");
Method1();
}
}

class Derived : Base
{
public override void Method1()
{
Console.WriteLine("Derived.Method1");
base.Method2();
}
}
}

This results in an endless loop of :

Derived.Method1
Base.Method2
Derived.Method1
Base.Method2

because the call to Method1() in Base calls Derived's
implementation.
What
I
want is for the Method1 invocation in Base to call its (Base's)
implementation of Method1. The desired output would be:

Derived.Method1
Base.Method2
Base.Method1

Sorry I wasn't clearer before.

Depends much on what interface you want to expose. Did you try running
your
code? It would not run because B.Method1 is protected. So the first
thing
you need to do is make it public. But in that case, you would be
changing
the signature of A.Method1 which you are overriding and that is not
allowed.
The following will work, but may not exactly meet your requirements.

class MyApp

{

public static void Main()

{

D d = new D();

d.Method2();

}

}



class B

{

protected virtual void Method1()

{ Console.WriteLine("Inside B.Method1()"); }

}

class D : B

{

public void Method2()

{ base.Method1(); }

}


Is there a way to call a base class implementation of a protected
method
when Here's the scenario:

class MyApp
{
public static Main()
{
D obj=new D();

obj.Method1();
}
}


class B
{
protected void Method1()
{
}

protected void Method2()
{
//I want to call B's implementation of Method1 even
though
I'm
running as D's implementation of Method2;
//conceptually I want to do: this.base.Method1();
}
}

class D : B
{
override protected void Method1()
{
Method2();
}
}



Is this doable?

TIA

</joel>
 
Microsoft said:
I guess I'll have to start learning IL :-)

Thanks for the info. I hope MS adds this to C# soon. It doesn't come up
often but when you need it, you end up with a messy work-around.

Or use MC++ / C++/CLI. This language supports it.
I guess changing languages just for one feature would be a bit of an
overreaction, but since you consider learning IL anyways... ;)

hth
 
I'm surprised that no one mentioned MyClass in VB.NET, which does exactly
what you are asking about. It behaves as a me reference (this), except as if
all the methods were NotOverridable (non-virtual) on the base class.

And by searching Google for "MyClass equivalent C#", you are led to this:

http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88476.aspx


Which explains that C# doesn't support anything like MyClass.

-- russ
 
Back
Top