2009-03-12 14 views
2

Ich möchte ein Linq IQueryable Toolkit im Projekt auf .NET Compact Framework verwenden. Die Linq-Fähigkeiten in CF ist ein wenig shapred - d. H.: IQueryable-Schnittstelle ist nicht verfügbar. Also habe ich Bibliotheken von Drittanbietern gefunden, die fehlende Funktionalität implementieren, was ich brauche.Workaround für MethodBase.GetCurrentMethod() auf Compact Framework 3.5

Jetzt habe ich ein Problem mit der fehlenden Methode "MethodBase.GetCurrentMethod()". Es gibt ca. 100 Methoden, die diese Methode verwenden. Also brauche ich nicht den genauen Klon von "GetCurrentMethod()". Die Problemumgehung für diesen speziellen Fall ist ausreichend.

Probe von Originalcode:

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) })); 
} 

posibile Die Lösung ist "(Methodinfo) MethodBase.GetCurrentMethod()" mit spezifischem Methodenaufruf ersetzen. Zum Beispiel: GetMethod_Any_TSource_On_Source() und GetMethod_Any_TSource_On_Source_With_Predicate_TSource_Bool().

Ich suche nach einer handlichen Lösung, wie man es löst.

Antwort

1

Siehe this discussion

Es ist im Wesentlichen unmöglich, im Klar verwalteten Code in Compact Framework 1.0.

In 2.0 ist es möglich, aber fehleranfällig, zerbrechlich und vor allem nicht garantiert korrekt (ein schwerwiegender Fehler).

Ich würde stattdessen vorschlagen, ein Makro zu schreiben, das alle Instanzen von "((MethodInfo) MethodBase.GetCurrentMethod())" finden und die Methode ermitteln kann, in der sie sich befinden. .

einfach jede Zeile wie so

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

zu throw new Exception ((Method) MethodBase.GetCurrentMethod()) Name) umzuwandeln;

  • Compile für den nicht kompakten Rahmen (mit der Hand zur Festsetzung der Standorte, die die Regex pleite ersetzen, sollte es nicht viele sein)
  • Run jede Methode in den Klassen, in denen durch Reflexion geschah Ersatz
  • fangen die resultierende Ausnahmen und drucken Sie die Nachricht (Methodenname) und die erste Zeile des Stack-Trace. Diese

gibt Ihnen dann eine Liste, was Sie brauchen, direkt an jedem Aufrufort setzen in (wahrscheinlich durch eine träge erstellt statisches Feld gesichert Halten der Method für jeden.

Dies ist umständlich, aber vielleicht Arbeit recht gut als eine einmalige Aktion pre Rahmen Update obwohl es von Hand genauso schnell um ehrlich zu sein zu gehen und tun es auch sein mag.

+1

+1 sehr Vielen Dank für die Antwort. Actualy ich habe schreibe alle ".GetCurrentMethod" als "((Func )% TypeName%.% MethodName%). Methode". Es war eine Menge Arbeit, aber die Leistung ist besser als ".GetCurrentMethod" aufrufen und es funktioniert. Ich hatte Glück, dass ich es nur in statischen Methoden brauchte, also war das Umschreiben nicht so komplex. Der Weg mit Ausnahme werfen ist wirklich peinlich, und es tötet eine Leistung, wenn es häufig verwendet wird. Aber danke für den Vorschlag. – TcKs

+0

Cool, hast du es mit der Hand gemacht oder ein Werkzeug benutzt? Wenn Sie das mit einem Werkzeug vielleicht als Antwort hinzufügen könnten (und es akzeptieren), wäre es für andere nützlich. – ShuggyCoUk

+0

Ich habe es von Hand gemacht, weil Generika in Klassen und Methoden sehr häufig verwendet wurden. Eigentlich habe ich es schon fast gemacht, wie du geschrieben hast. Also gut, ich kann deine Antwort akzeptieren. – TcKs

Verwandte Themen