Which class is calling?

  • Thread starter Thread starter Greg Bacchus
  • Start date Start date
G

Greg Bacchus

I have a base class with a method that is to be called in the constructor of
the inheritting classes. Is there any way of determining, say, the Type of
the class that is calling it.

e.g.

class A
{
public A()
{
AddStuff();
}

protected void AddStuff()
{
//do stuff
}
}

class B : A
{
public B()
{
AddStuff();
}
}

class C : B
{
public C()
{
AddStuff();
}
}

So when I create an instance of C, AddStuff() will be called by each of the
three constructors, but I need to know which constructor was calling it (so
in know the context to which I should add the stuff).

Hope that makes some sort of sense.

Greg
 
Hi Greg,

You would have to examine the call stack which is expensive and unreliable
IMO.
You might consider another way to solve your problem.
 
You really need to change your design. Why can't each constructor do its own
init as appropriate? if all classes have a block of init code in common,
this can go in a protected method in the base class.

Just in case someone suggests it, calling virtual methods from a constructor
is a really bad idea, since the virtual method calls happen before any other
initialisation that the constructor does. This can produce unexpected
results.

Hope this helps

Regards

Ron
 
Miha,

I am curious, can you show examples of where the call stack is
unreliable? I'll definitely agree that it is expensive, but I haven't heard
claims that it is unreliable (and security would be compromised as a result,
because stack walks are done in order to handle a lot of the security in
..NET).
 
Hi Nicholas,

I am not sure on reliablity, AFAIK compiler could optimize some calls, do
things inline - stuff like that.
Even if it is not doing this already it can in future.
I didn't ever test it though.

--
Miha Markic - RightHand .NET consulting & software development
miha at rthand com

Nicholas Paldino said:
Miha,

I am curious, can you show examples of where the call stack is
unreliable? I'll definitely agree that it is expensive, but I haven't heard
claims that it is unreliable (and security would be compromised as a result,
because stack walks are done in order to handle a lot of the security in
.NET).


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Miha Markic said:
Hi Greg,

You would have to examine the call stack which is expensive and unreliable
IMO.
You might consider another way to solve your problem.

--
Miha Markic - RightHand .NET consulting & software development
miha at rthand com

constructor
Type
of of
the it
(so
 
I am not sure on reliablity, AFAIK compiler could optimize some calls, do
things inline - stuff like that.
Even if it is not doing this already it can in future.
I didn't ever test it though.

The JIT inlining functions can definitely have a nasty effect on a
stack trace. (I was suspicious of this until I actually saw it.) Here's
a program which demonstrates it:

using System;
using System.Diagnostics;

class Test
{
static StackTrace GetTrace()
{
return new System.Diagnostics.StackTrace();
}

static StackTrace Intermediate()
{
return GetTrace();
}

static void Main(string[] args)
{
Console.WriteLine (Intermediate());
}
}

Compiled with debug:
at Test.GetTrace()
at Test.Intermediate()
at Test.Main(String[])

Compiled without debug information:
at Test.Main(String[])

(Adding [MethodImpl(MethodImplOptions.NoInlining)] to Intermediate and
GetTrace makes it get it right.)
 
greg,

it does sound like your design could be organized in a better way. i'm not
exactly sure what behavior you're going for, but it seems like you want
this:

when C is constructed, the C object calls the B constructor, which calls
the A constructor, which adds stuff for A, then the B constructor adds
stuff for B, then the C constructor adds stuff for C.

if AddStuff works in different ways depending on which class it is called
from, eg it does action 1 when A calls it, action 2 when B calls it, and
action 3 when C calls it, then AddStuff should really be a different method
in each of these classes. i suggest looking into the virtual and new
keywords for this. this is a common problem in object oriented development
which is solved by Polymorphism. i've posted one example below - notice i
defined A's AddStuff with the virtual keyword and the others are defined
with the new keyword in the method signature. when you run this code, the
output is A->B->C.

let me know if you have any other questions.

jeff.

namespace ConsoleApplication4
{
class Class1
{
static void Main(string[] args)
{
C c = new C();
Console.ReadLine();
}
}

class A
{
public A()
{
this.AddStuff();
}

public virtual void AddStuff()
{
Console.WriteLine("AddStuff - A");
}
}
class B : A
{
public B()
{
this.AddStuff();
}

public new void AddStuff()
{
Console.WriteLine("AddStuff - B");
}
}
class C : B {
public C()
{
this.AddStuff();
}

public new void AddStuff()
{
Console.WriteLine("AddStuff - C");
}
}
}

--

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

Note: For the benefit of the community-at-large, all responses to this
message are best directed to the newsgroup/thread from which they
originated.
 
Hi Greg

I posted this last night, but it didn't turn up on the NG - not an unknown
event methinks.

You really need to change your design. Why can't each constructor do its own
init as appropriate? if all classes have a block of init code in common,
this can go in a protected method in the base class.

Just in case someone suggests it, calling virtual methods from a constructor
is a really bad idea, since the virtual method calls happen before any other
initialisation that the constructor does. This can produce unexpected
results.

Hope this helps

Regards

Ron
 
Back
Top