views:

65

answers:

4

.Net 3.5, using C#

I have an instance of a class (A) that has been called via a virtual method from a derived class (B). Within the method (a method of class A) I have discovered the Type of class B that has made the call, and using reflection I have examined class B and discovered a property whose value I want to access.

Is there any way via reflection to get the instance reference to class B? The only object I have is my ‘this’ reference.

[ Edit ]

By way of explaining that I'm not totally nuts for needing to do this: My class is T4NmpBase (class A). I have no control over the class in which I am inheriting (TextTransformation) or the class that inherits from me (TextTemplating - class B). I would like to use the "Host" property if it exits but do not want to put any burden on the programmer who is writing the text templating code that generates the TextTransformation class.

//
// this is my class
//
public abstract partial class T4NmpBase : Microsoft.VisualStudio.TextTemplating.TextTransformation {

    public override void Initialize()
    {
        //
        // determine derived class info and get value of "Host" property if it exists
        //
    }

}


//
// this class is generated by T4 in a project that I have no control over
//
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")]
public partial class PPTest : T4_NMP_Base.T4NmpBase {

    public virtual global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost Host { ... }

    public override void Initialize()
    {
        base.Initialize();
    }
}
A: 

If I understand correctly, from class A you want to access the functionality of the current instance through its concrete type B. Unless the member is not accessible to A because it's non-public, defined in another assembly, etc you don't need reflection. The following will work if the code in class A can see the members of derived class B.

B thisAsB = this as B;
if (thisAsB != null) {
   // ...
}

But it does call into question the design of the class because class A should not have to know anything about its subclasses.

Josh Einstein
+1  A: 

In your case (assuming I follow correctly) your this reference is really your class (B) type, so you can use that to get the value of the property. So, just to make sure I follow correctly, you've got something that looks like:

public class ClassA
{
    public virtual void VirtualMethod()
    {
        // Do your property investigation here
    }
}

public class ClassB: ClassA
{
    public override void VirtualMethod()
    {
        // Code for ClassB
    }
}

And you are invoking the virtual method using something like:

ClassA instance = new ClassB();
instance.VirtualMethod()

So if that is the case then you should be able to get the value of the property by:

PropertyInfo proeprtyOnClassB // Assume you got this already via reflection
object propertyValue = propertyOnClassB.GetGetMethod().Invoke(this,null);
ckramer
This is the first thing I tried but it didn't work. Woke up this morning and realized that I wasn't doing this in a virtual method but was doing it in the constructor! Won't work in the constructor because class B is not constructed yet! Moved the code into the virtual function where it should have been and it now works! Thanks.
jr
+1  A: 

This sounds like a real problem with your design.

Is it possible to take Class B's property in question and make it a virtual property of Class A? Then you can override it in B but still access B's property from A. For example:

class A
{
    public virtual string P
    {
        get { return "A"; }
    }

    public A()
    {
        Console.WriteLine(this.P);
    }
}

class B : A
{
    public override string P
    {
        get { return "B"; }
    }

    public B() : base() { }
}

When using:

B b = new B(); // prints "B"
Quick Joe Smith
A: 

If you know the class and property at compile time (and it sounds like you do) then it's easy:

ClassB useProperty = this as ClassB;

string a = useProperty.Whatever;

Although this does sound a bit hinky (I'm not sure why you'd have a method in A that accesses a property in B, but hey, it's your program).

jmoreno