如何在 C# 2.0 中支持泛型表达式

Posted

技术标签:

【中文标题】如何在 C# 2.0 中支持泛型表达式【英文标题】:How do I support generic expression in C# 2.0 【发布时间】:2014-02-06 08:53:39 【问题描述】:

我有一些为 C# 4.0+ 编写的代码,我确实需要使用 C# 2.0 编译器进行编译。

下面的sn-ps我真的不怎么写,为了支持同样的功能:

public sealed class MyClass

    private static readonly GenericStaticMethod _deserializeHelper = new GenericStaticMethod(() => DeserializeHelper<object>(null, null, null));
    //...


public sealed class GenericStaticMethod

    private readonly MethodInfo methodToCall;

    public GenericStaticMethod(Expression<Action> methodCall)
    
        var callExpression = (MethodCallExpression)methodCall.Body;
        methodToCall = callExpression.Method.GetGenericMethodDefinition();
    

    public object Invoke(Type[] genericArguments, params object[] arguments)
    
        try
        
            return methodToCall
                .MakeGenericMethod(genericArguments)
                .Invoke(null, arguments);
        
        catch (TargetInvocationException ex)
        
            throw ex.Unwrap();
        
    

不能这样写的表达式是:

() => DeserializeHelper<object>(null, null, null)

如果不修改 GenericStaticMethod(),则无法直接替换委托:

delegate()  return DeserializeHelper<object>(null, null, null); 

重写GenericStaticMethod 可以接受,但我不知道该怎么做。

【问题讨论】:

【参考方案1】:

在您的情况下,您只是不能使用表达式树,它们只能在以后的版本中获得编译器支持。但是,如果您使用它的唯一原因是以强类型方式获取 MethodInfo,则您不需要这样做。

public sealed class MyClass

    private static readonly GenericStaticMethod _deserializeHelper = new GenericStaticMethod(new Action<object, object, object>(DeserializeHelper<object>));


public sealed class GenericStaticMethod

    private readonly MethodInfo methodToCall;

    public GenericStaticMethod(Delegate methodCall)
    
        methodToCall = methodCall.Method.GetGenericMethodDefinition();
    

您需要将Action&lt;object, object, object&gt; 更改为与DeserializeHelper&lt;object&gt; 的签名匹配的委托类型。

【讨论】:

这是一个非常优雅的解决方案。谢谢!我不得不用Action&lt;&gt; 替换Func&lt;&gt;,因为该函数有一个返回值,但其余的工作正常。

以上是关于如何在 C# 2.0 中支持泛型表达式的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET 2.0 中编写一个简单的类似表达式的类?

C# 2.0 中的新增功能03 匿名方法

表达式树练习实践:C#值类型引用类型泛型集合调用函数

C# 2.0 新特性(上)

C# 委托 —— 委托 泛型委托与Lambda表达式

C#复习总结细说泛型委托