2010-06-20 4 views
2

.Net 3.5, en utilisant C#Comment obtenir une référence à une instance d'une classe dérivée à partir d'une classe de base

J'ai une instance d'une classe (A) qui a été appelé par une méthode virtuelle à partir d'un classe dérivée (B). Dans la méthode (une méthode de classe A) j'ai découvert le type de classe B qui a fait l'appel, et en utilisant la réflexion j'ai examiné la classe B et découvert une propriété dont je veux accéder à la valeur.

Existe-t-il un moyen par réflexion pour obtenir la référence d'instance à la classe B? Le seul objet que j'ai est ma référence 'this'.

[Modifier]

A titre d'expliquer que je ne suis pas complètement fou pour avoir besoin de faire ceci: Ma classe est T4NmpBase (classe A). Je n'ai aucun contrôle sur la classe dans laquelle j'hérite (TextTransformation) ou la classe qui hérite de moi (TextTemplating - class B). Je voudrais utiliser la propriété "Host" si elle se termine mais ne veut pas mettre n'importe quel fardeau sur le programmeur qui écrit le code de modèle de texte qui génère la classe TextTransformation.

// 
// 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(); 
    } 
} 
+0

Il est possible avec la réflexion, mais il ressemble vraiment à un problème avec votre conception. N'oublie pas que la réflexion est très lente. Pourtant, vous pourriez avoir une bonne raison pour cela, je suppose. Tu n'as pas dit. –

Répondre

1

Dans votre cas (en supposant que je suivre correctement) votre référence thisest vraiment votre type de classe (B), de sorte que vous pouvez utiliser pour obtenir la valeur de la propriété. Donc, pour vous assurer que je suivre correctement, vous avez quelque chose qui ressemble à:

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

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

Et vous appelez la méthode virtuelle en utilisant quelque chose comme:

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

Donc, si tel est le cas alors vous devriez être en mesure d'obtenir la valeur de la propriété par:

PropertyInfo proeprtyOnClassB // Assume you got this already via reflection 
object propertyValue = propertyOnClassB.GetGetMethod().Invoke(this,null); 
+0

C'est la première chose que j'ai essayé mais cela n'a pas fonctionné. Je me suis réveillé ce matin et j'ai réalisé que je ne le faisais pas dans une méthode virtuelle mais que je le faisais dans le constructeur! Ne fonctionnera pas dans le constructeur car la classe B n'est pas encore construite! Déplacé le code dans la fonction virtuelle où il aurait dû être et cela fonctionne maintenant! Merci. –

0

Si je comprends bien, de la classe A que vous voulez accéder à la fonctionnalité de l'instance actuelle par son type concret B. À moins que le membre n'est pas accessible à A, car il est non-publique, défini dans une autre assemblée, etc vous n'avez pas besoin de réflexion. Ce qui suit ne fonctionnera que si le code en classe A peut voir les membres de la classe dérivée B.

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

Mais il ne remet en cause la conception de la classe parce que la classe A ne devrait pas avoir à connaître quoi que ce soit au sujet de ses sous-classes.

1

Cela ressemble à un vrai problème avec votre conception.

Est-il possible de prendre la propriété de classe B en question et en faire une propriété virtuelle de classe A? Ensuite, vous pouvez le remplacer dans B, mais encore accéder à la propriété de B à A. Par exemple:

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() { } 
} 

Lorsque vous utilisez:

B b = new B(); // prints "B" 
Questions connexes