views:

528

answers:

1

I want use a Linq IQueryable Toolkit in project on .NET Compact Framework. The Linq capabilities in CF is little bit shapred - i.e.: IQueryable interface is not available. So I've found third party libraries, which implements missing functionality what I need.

Now I have problem with missing method "MethodBase.GetCurrentMethod()". There is cca 100 methods, which uses this method. So I don't need the exact clone of "GetCurrentMethod()". The workaround way for this specific case is enough.

Sample of original code:

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

The posibile solution is replace "(MethodInfo)MethodBase.GetCurrentMethod()" with specific method call. For example: GetMethod_Any_TSource_On_Source() and GetMethod_Any_TSource_On_Source_With_Predicate_TSource_Bool().

I search for some handy solution how to solve it.

+1  A: 

See this discussion

It is essentially impossible in plain managed code in Compact Framework 1.0.

In 2.0 is it possible but error prone, fragile and most importantly NOT guaranteed to be correct (a serious flaw).

I would suggest instead writing a macro which can find all instances of "((MethodInfo)MethodBase.GetCurrentMethod())" and determinte the method in which they reside.

Simply converting every line like so

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

to throw new Exception((MethodInfo)MethodBase.GetCurrentMethod()).Name);

  • Compile for the non compact framework (fixing by hand the locations that the regex replace broke, there shouldn't be many)
  • Run every method in the classes where replacements happened by reflection
  • catch the resulting exceptions and print the message (method name) and the first line of the stack trace.

This then gives you a list of what you need to put in directly at each call site (probably backed up by a lazily created static field holding the MethodInfo for each one.

This is cumbersome but might work reasonably well as a one off action pre framework update though to be honest it might be just as quick to go through and do it by hand.

ShuggyCoUk
+1Thank you very much for reply.Actualy I've rewrite all ".GetCurrentMethod" as "((Func<T1, T2, ...>)%TypeName%.%MethodName%).Method". It was a lot of work, but the performance is better than calling ".GetCurrentMethod" and it works. I had luck, that I required used it only in static methods, so rewriting it was not so complex.The way with throwing exception is realy awkward, and it kill a performance, if it is used frequently. But thanks for suggestion.
TcKs
Cool, did you do it by hand or use a tool? If by a tool perhaps you could add that as an answer (and accept it) since it would be useful to others.
ShuggyCoUk
I did it by hand, because there was used generics in classes and methods a lot.Actually I did it already almost, as you wrote. So ok, I can accept your answer.
TcKs
OK thanks, if you had any info or recommendations feel free to edit my answer as you like.
ShuggyCoUk