Обходной путь для MethodBase.GetCurrentMethod () в Compact Framework 3.5 - PullRequest
2 голосов
/ 12 марта 2009

Я хочу использовать Linq IQueryable Toolkit в проекте на .NET Compact Framework. Возможности Linq в CF немного ограничены - т.е. интерфейс IQueryable недоступен. Итак, я нашел сторонние библиотеки, которые реализуют недостающую функциональность, что мне нужно.

Теперь у меня проблема с отсутствующим методом "MethodBase.GetCurrentMethod ()". Существует около 100 методов, которые используют этот метод. Поэтому мне не нужен точный клон "GetCurrentMethod ()". Обходного пути для этого конкретного случая достаточно.

Образец исходного кода:

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

Возможное решение - заменить "(MethodInfo) MethodBase.GetCurrentMethod ()" конкретным вызовом метода. Например: GetMethod_Any_TSource_On_Source () и GetMethod_Any_TSource_On_Source_With_Predicate_TSource_Bool ().

Я ищу какое-нибудь удобное решение, как его решить.

1 Ответ

1 голос
/ 22 апреля 2009

См. это обсуждение

Это практически невозможно в простом управляемом коде в Compact Framework 1.0.

В 2.0 это возможно, но подвержено ошибкам, хрупко и, что самое главное, НЕ гарантированно будет правильным (серьезный недостаток).

Я бы предложил вместо этого написать макрос, который может найти все экземпляры "((MethodInfo) MethodBase.GetCurrentMethod ())" и определить метод, в котором они находятся.

Просто конвертируем каждую строку следующим образом

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

в бросить новое исключение ((MethodInfo) MethodBase.GetCurrentMethod ()). Name);

  • Скомпилируйте для некомпактного каркаса (исправляя вручную места, которые заменяет регулярное выражение, их не должно быть много)
  • Запустить каждый метод в классах, где замены произошли с помощью отражения
  • перехватывает возникающие исключения и печатает сообщение (имя метода) и первую строку трассировки стека.

Затем вы получите список того, что вам нужно вставить непосредственно на каждом сайте вызовов (вероятно, подкрепленный лениво созданным статическим полем, содержащим MethodInfo для каждого.

Это громоздко, но может работать достаточно хорошо, как предварительное обновление фреймворка, но если честно, пройти его можно и так быстро, и сделать это вручную.

...