2009-03-12 8 views
2

Je souhaite utiliser une boîte à outils Linq IQueryable dans un projet sur .NET Compact Framework. Les capacités Linq dans CF sont un peu minuscules - à savoir: l'interface IQueryable n'est pas disponible. J'ai donc trouvé des bibliothèques tierces, qui implémentent des fonctionnalités manquantes dont j'ai besoin.Solution de contournement pour MethodBase.GetCurrentMethod() sur Compact Framework 3.5

Maintenant, j'ai un problème avec la méthode manquante "MethodBase.GetCurrentMethod()". Il existe des méthodes cca 100 qui utilisent cette méthode. Donc je n'ai pas besoin du clone exact de "GetCurrentMethod()". La solution de contournement pour ce cas spécifique est suffisante.

Exemple de code original:

public static bool Any<TSource>(this IQueryable<TSource> source) { 
    return source.Provider.Execute<bool>(Expression.Call(null, ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { source.Expression })); 
} 

public static bool Any<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) { 
    return source.Provider.Execute<bool>(Expression.Call(null, ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { source.Expression, Expression.Quote(predicate) })); 
} 

La solution est posibile remplacer "(MethodInfo) MethodBase.GetCurrentMethod()" avec appel de méthode spécifique. Par exemple: GetMethod_Any_TSource_On_Source() et GetMethod_Any_TSource_On_Source_With_Predicate_TSource_Bool().

Je cherche une solution pratique pour le résoudre.

Répondre

1

Voir this discussion

Il est pratiquement impossible dans le code managé clair dans Compact Framework 1.0.

Dans 2.0 est-il possible mais sujet à erreur, fragile et surtout pas garanti d'être correct (un sérieux défaut).

Je suggère plutôt d'écrire une macro qui peut trouver toutes les instances de "((MethodInfo) MethodBase.GetCurrentMethod())" et de déterminer la méthode dans laquelle ils résident.

convertir simplement chaque ligne comme si

".*\(\(MethodInfo\)MethodBase\.GetCurrentMethod\(\)\).*" 

à throw new Exception ((MethodInfo) MethodBase.GetCurrentMethod()) Nom).

  • Compile pour le cadre non compact (fixation à la main les endroits que le regex remplacent cassé, il ne devrait pas être beaucoup)
  • Exécuter toutes les méthodes dans les classes où les remplacements se sont produits par la réflexion
  • attraper la exceptions résultantes et imprimer le message (nom de la méthode) et la première ligne de la trace de la pile.

Cela vous donne une liste de ce que vous avez besoin de mettre directement sur chaque site d'appel (probablement soutenu par un

champ statique créé paresseusement tenant le MethodInfo pour chacun. Ceci est lourd, mais pourrait fonctionner raisonnablement bien comme une action un hors cadre avant la mise à jour mais pour être honnête, il pourrait être tout aussi rapide à passer et le faire à la main.

+1

+1 Merci beaucoup pour la réponse. J'ai actualy réécrire tous ".GetCurrentMethod" comme "((Func )% TypeName%.% MethodName%). Méthode". C'était beaucoup de travail, mais la performance est meilleure que d'appeler ".GetCurrentMethod" et cela fonctionne. J'ai eu de la chance, je ne l'ai utilisé que dans des méthodes statiques, donc réécrire n'était pas si complexe. La manière avec l'exception de lancer est vraiment maladroite, et elle tue une performance, si elle est utilisée fréquemment. Mais merci pour suggestion. – TcKs

+0

Cool, as-tu fait à la main ou utilisé un outil? Si par un outil vous pourriez peut-être ajouter cela comme une réponse (et l'accepter) car cela serait utile aux autres. – ShuggyCoUk

+0

Je l'ai fait à la main, parce qu'il y avait beaucoup de génériques utilisés dans les classes et les méthodes. En fait, je l'ai déjà fait presque, comme vous l'avez écrit. Alors ok, je peux accepter votre réponse. – TcKs