【问题标题】:Workaround for MethodBase.GetCurrentMethod() on Compact Framework 3.5Compact Framework 3.5 上 MethodBase.GetCurrentMethod() 的解决方法
【发布时间】:2009-03-12 15:51:28
【问题描述】:

我想在 .NET Compact Framework 的项目中使用 Linq IQueryable Toolkit。 CF 中的 Linq 功能有点不同 - 即:IQueryable 接口不可用。所以我找到了第三方库,它实现了我需要的缺失功能。

现在我遇到了缺少方法“MethodBase.GetCurrentMethod()”的问题。有 cca​​ 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()。

我正在寻找一些方便的解决方案如何解决它。

【问题讨论】:

    标签: .net linq generics reflection compact-framework


    【解决方案1】:

    this discussion

    在 Compact Framework 1.0 的纯托管代码中基本上是不可能的。

    在 2.0 中是可能的,但容易出错,脆弱,最重要的是不能保证正确(一个严重的缺陷)。

    我建议改为编写一个宏,它可以找到“((MethodInfo)MethodBase.GetCurrentMethod())”的所有实例并确定它们所在的方法。

    像这样简单地转换每一行

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

    到 抛出新异常((MethodInfo)MethodBase.GetCurrentMethod()).Name);

    • 为非紧凑框架编译(手动修复正则表达式替换损坏的位置,应该不多)
    • 在通过反射发生替换的类中运行每个方法
    • 捕获产生的异常并打印消息(方法名称)和堆栈跟踪的第一行。

    然后,这会为您提供一个列表,其中列出了您需要直接在每个调用站点输入的内容(可能由一个惰性创建的静态字段备份,该字段保存每个调用站点的 MethodInfo。

    这很麻烦,但作为一个一次性的预框架更新可能工作得相当好,但说实话,手动完成它可能同样快。

    【讨论】:

    • +1 非常感谢您的回复。实际上,我已将所有“.GetCurrentMethod”重写为“((Func)%TypeName%.%MethodName%).Method”。工作量很大,但性能比调用“.GetCurrentMethod”要好,而且它可以工作。我很幸运,我只需要在静态方法中使用它,所以重写它并不复杂。抛出异常的方式真的很尴尬,如果经常使用它会破坏性能。不过谢谢你的建议。
    • 酷,你是用手做的还是用工具做的?如果通过工具,也许您可​​以将其添加为答案(并接受它),因为它对其他人有用。
    • 我是手工完成的,因为在类和方法中使用了很多泛型。实际上,正如您所写的,我几乎已经做到了。好吧,我可以接受你的回答。
    • 好的,谢谢,如果您有任何信息或建议,请随时根据需要编辑我的答案。
    猜你喜欢
    • 2010-09-26
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多