2010-11-29 16 views
-1

J'ai la construction suivante:Obtenez le Propertyname de posséder le type C#

class Bla 
{ 
    public string Hello() 
    { 
     return "Hello my name is " + GetMyVariableName(); 

    } 

    private string GetMyVariableName() 
    { 
     return "";//do magic here to determine the Variable name at the class that owns the Property 
    } 
} 

class Fasel 
{ 
    public Bla SomeProperty { get; set; } 
    public Bla AnotherProperty { get; set; } 

    void DoSomeAction() 
    { 
     SomeProperty = new Bla(); 
     AnotherProperty = new Bla(); 

     string name = SomeProperty.Hello(); //this sould return "Hello my name is SomeProperty" 

     name = AnotherProperty.Hello(); ////this sould return "Hello my name is AnotherProperty" 
    } 
} 

Cela semble facile à résoudre que je viens de faire les choses de réflexion pour déterminer le nom de posséder classe, mais dans mon cas particulier je peux » t fais ça. J'ai besoin de savoir dans la propriété quel est le nom dans la classe qui le possède.

+0

Vous ne pouvez pas faire cela sans créer votre propre version du CLR. – SLaks

Répondre

2

Ceci est complètement, absolument impossible.

Une seule instance peut être référencée par plusieurs propriétés; il n'y a pas de connexion entre un objet et les propriétés auxquelles il est référencé. (Sauf dans le GC, qui ne vous le dira pas)

En outre, l'inlining JIT peut signifier que la propriété ne sera pas nécessairement impliquée du tout.
De plus, les noms de variables locaux n'existent pas dans les fichiers binaires optimisés.

+0

Eh bien pas impossible, vraiment vraiment très dur. Vous pouvez obtenir la méthode Hello en utilisant le Stack Trace. Ensuite, utilisez le corps de la méthode pour le comprendre. Bien que même à partir de là, je ne peux pas voir un bon moyen de le faire. Mais à toutes fins utiles, votre réponse est à peu près exacte. –

+0

@Yuriy: Non; c'est vraiment impossible. Vous ne pouvez pas déterminer de façon fiable où, dans la méthode, votre appel a pris naissance pour des méthodes non triviales. (Sauf peut-être si vous dupliquez JITter, ou créez un second processus et attachez-le au premier en tant que débogueur géré, les deux étant _insane_ et impossible) – SLaks

+0

Votre question signifie que quelque chose ne va vraiment pas dans votre conception, mais Cela devrait être possible si vous avez seulement besoin de supporter les propriétés (et non les variables locales). Vous pouvez regarder la trace de la pile pour trouver l'objet dont la méthode appelle Bla.Hello(), puis utiliser la réflexion pour parcourir toutes les propriétés et les champs de l'objet, et en trouver une dont la valeur est l'instance Bla. – Ran

1

Je ne pense pas que ce que vous demandez est possible. Peut-être une façon de le faire serait pour le constructeur de Bla prendre une chaîne, puis lorsque vous créez l'instance, vous pouvez passer dans la chaîne:

SomeProperty = new Bla("SomeProperty"); 
AnotherProperty = new Bla("AnotherProperty"); 
+0

qui est la solution actuelle, mais si quelqu'un renomme la propriété et oublie le constructeur, la logique derrière échoue mais le compilateur ne peut pas vérifier cela. – Kolja

1

Il n'y a aucun moyen que vous pouvez reliabily faire avec réflexion et c'est une idée terrible à vouloir en premier lieu. Il est possible d'invoquer une méthode sur instance sans jamais déclarer une variable pour cela. Par exemple:

string name=new Bla().Hello(); 

Dans ce scénario, quelle serait votre méthode d'impression?

+0

+1 J'ai oublié ce contre-exemple – SLaks