2009-06-02 5 views
1

Désolé pour les pauvres explaination du problèmeC# Obtenir l'implémentation Delegate (Func) à partir d'une classe concrète via une réflexion?

question réécriture totalement

je la méthode suivante:

public TReturn FindCached<TSearch, TReturn>(Func<TSearch, TReturn> searchMethod) 
      where TSearch : ISearchSpecification 
      where TReturn : class 
     { 
      SearchSpecification spec = new GetConcreteSearchSpecification<TSearch>(); 

      //insert magic here to get an attribute from the method on 
      //the spec class that searchMethod invokes on the line below 

      return searchMethod(spec); 
     } 

J'ai donc un délégué (searchMethod) et un objet (spec) que je vouloir invoquer le délégué sur. Je veux inspecter l'objet (spec) pour trouver un attribut personnalisé sur la méthode que searchMethod appellera lorsqu'il sera appelé.

Espérons que cela soit plus clair.

Merci

+0

Je ne suis pas sûr que vos fragments de sens? ... vouliez-vous vous référer à 'TSearch' où vous avez dit 'T' dans la clause where? – jerryjvl

+0

Ce que vous voulez dire n'est pas très clair. Quelle est la première déclaration destinée à être? Une méthode avec les contraintes après? Qu'est-ce que TSearch? MySearchSpec est-il censé être une déclaration de variable? Quelle "implémentation concrète" voulez-vous inspecter? –

+0

* Où * est l'attribut utilisé? Pouvez-vous illustrer? –

Répondre

1

En supposant que vous vouliez dire searchMethod être une variable de type Func<TSearch, TReturn> et mySearchSpec comme une mise en œuvre de ISearchSpecification<TSearch>, alors vous demandez essentiellement comment obtenir des attributs sur une classe.

Pour cela, utilisez quelque chose comme:

object[] attrs = typeof(mySearchSpec).GetCustomAttributes(false); 

Si l'on suppose que le type mySearchSpec est public, sinon vous devrez peut-être une surcharge différente pour GetCustomAttributes

Addendum:
Sur la base de votre question révisée , pour obtenir les attributs d'une méthode sur le type réel de spec utilisé:

Type t = spec.GetType(); 
MethodInfo m = t.GetMethod("nameOfMethodToBeCalledHere"); 
object[] attrs = m.GetCustomAttributes(false); 

Encore une fois, notez que vous pouvez avoir besoin de surcharges pour GetMethod ou GetCustomAttributes selon l'implémentation de la classe réelle.

Note:
Il ne semble cependant que vous demandez peut-être la méthode appelée à return searchMethod(spec);, mais qui est searchMethod et non une méthode sur spec du tout.

Si vous voulez des attributs sur searchMethod (rien à voir avec spec):

MethodInfo m = searchMethod.Method; 
object[] attrs = m.GetCustomAttributes(false); 

Je pense que couvre maintenant toutes les permutations de sens ...

+0

Merci pour votre réponse, je n'étais pas clair dans ma question: j'essaie en fait d'obtenir un attribut personnalisé de la méthode de la spécification que searchMethod invoque. –

+0

Merci encore ... mon problème exact est d'obtenir "nameOfMethodToBeCalledHere" à partir du searchMethod Func searchMethod.Method.Name est peuplé avec des trucs backing field :( –

+0

Vous avez dépassé votre cible d'une propriété ... voir ma dernière note;) – jerryjvl

0

Ceci est tout à fait une question confuse, nous allons voir si je l'ai droit:

  • Vous avez une fonction lambda (que vous décrivez en tant que délégué) appelée searchMethod.
  • Vous avez une usine modèle objet généré appelé spec

Vous avez une méthode quelque part comme ceci:

[MyCustomAttribute] 
public RetClass MyMethod(SearchSpecification input) { 
    return input.GetRetClass(); 
} 

Et vous appelez cette méthode avec:

var result = FindCached(MyMethod); 

Et dans FindCached vous voulez trouver MyCustomAttribute - dans ce cas, la réponse de jerryjvl est juste.

Votre problème est que vous pouvez également faire:

var result = FindCached(x => x.GetRetClass()); 

Je ne suis pas sûr de votre description que ce soit un attribut sur l'x.GetRetClass() que vous voulez réellement. Dans ce cas, vous devez séparer le lambda en utilisant des expressions, mais je ne le recommanderais pas - une déclaration lambda plus complexe aboutira à un délégué anonyme, qui est une boîte noire lorsque vous essayez de l'analyser au moment de l'exécution.

Au lieu de cela, comme vous utilisez la réflexion de toute façon, il pourrait être plus facile de transmettre le nom de la méthode que vous voulez au lieu de la référence délégué:

var result = FindCached("GetRetClass"); 
0

J'ai couru dans une situation similaire, la réponse de jerryjvl expliqué exactement ce que je voulais. Je voulais créer une méthode de profilage générique, où je pouvais calculer le temps d'exécution d'une méthode et récupérer le nom de la méthode en utilisant la réflexion à des fins de journalisation.

Le MethodInfo était la clé.

Là où j'ai une méthode comme:

public static bool TimeMethod(Func<bool> someMethod) 

Et puis plus tard, je veux obtenir dynamiquement son nom ou des attributs en dehors.

MethodInfo m = someMethod.Method; 
object[] attrs = m.GetCustomAttributes(typeof(MonitoringDescriptionAttribute), true); 
string name = m.Name; 

Vive