转换表达< Func< TDocument,object>>表达<功能< TDocument,TOutput>> [英] Convert Expression<Func<TDocument, object>> to Expression<Func<TDocument, TOutput>>

查看:108
本文介绍了转换表达< Func< TDocument,object>>表达<功能< TDocument,TOutput>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下表达式,类型为表达式< Func< TDocument,object>>

  x => x.Name 

现在,我不知道 x的类型。在编译时命名,但是现在它在运行时,因为它存储在一个类型中。



如何将我的表达式转换为类型表达式&FunC< TDocument,TOutput>> 其中 TOutput 是一个类型,在编译时不知道?

解决方案

你只需要在转换表达式中包装原始表达式的 Body ,然后重建lambda。以下是我可以如何使用泛型:

 表达式&FunC< TInput,TReturn> ;> ConvertReturnValue< TInput,TReturn>(
表达式< Func< TInput,object>> inputExpression)
{
表达式convertedExpressionBody = Expression.Convert(
inputExpression.Body,typeof(TReturn )
);

返回Expression.Lambda convertedExpressionBody,inputExpression.Parameters
);
}

用法:

 表达式< Func< TDocument,object>> inputExpression = d => d.Name; 

表达式< Func< TDocument,string>> convertedExpression
= ConvertReturnValue< TDocument,string>(inputExpression);

//测试。
TDocument doc = new TDocument {Name =Zzz};
string name = convertedExpression.Compile()。Invoke(doc);

Assert.Equal(Zzz,name);

无泛型



如果您不能使用泛型,因为您在编译时不知道返回类型, Expression.Lambda 实际上提供了非泛型重载,您可以使用它this:

  Expression ConvertReturnValue< TInput>(Expression< Func< TInput,object>> inputExpression,类型returnType)
{
Expression convertedExpressionBody = Expression.Convert(inputExpression.Body,returnType);

返回Expression.Lambda(convertedExpressionBody,inputExpression.Parameters);
}

上述仍然返回一个表达式&FunC< TInput ,TReturn>> (upcast到非泛型 Expression )。如果需要,您可以稍后下载:

 表达式< Func< TDocument,object>> inputExpression = d => d.Name; 

表达式< Func< TDocument,string>> convertExpression
=(表达式& Func< TDocument,string>>)ConvertReturnValue(inputExpression,typeof(string));

//测试。
TDocument doc = new TDocument {Name =Zzz};
string name = convertedExpression.Compile()。Invoke(doc);

Assert.Equal(Zzz,name);

附录



<请注意,对于struct返回类型,最终的表达式可能会如下所示:

 (TDocument d)=> (INT)(对象)d.ID; 


I have the following expression which is of type Expression<Func<TDocument, object>>

x => x.Name

Now, I don't know the type of x.Name at compile time, but I now it at runtime since it's stored in a Type.

How can I convert my expression to be of type Expression<Func<TDocument, TOutput>> where TOutput is a Type and not known at compile time?

解决方案

You just need to wrap the original expression's Body in a Convert expression and then rebuild your lambda. Here's how I would do it if I could use generics:

Expression<Func<TInput, TReturn>> ConvertReturnValue<TInput, TReturn>(
    Expression<Func<TInput, object>> inputExpression)
{
    Expression convertedExpressionBody = Expression.Convert(
        inputExpression.Body, typeof(TReturn)
    );

    return Expression.Lambda<Func<TInput, TReturn>>(
        convertedExpressionBody, inputExpression.Parameters
    );
}

Usage:

Expression<Func<TDocument, object>> inputExpression = d => d.Name;

Expression<Func<TDocument, string>> convertedExpression
    = ConvertReturnValue<TDocument, string>(inputExpression);

// Test.
TDocument doc = new TDocument { Name = "Zzz" };
string name = convertedExpression.Compile().Invoke(doc);

Assert.Equal("Zzz", name);

No generics

If you cannot use generics because you don't know the return type at compile time, Expression.Lambda actually offers a non-generic overload, which you can use like this:

Expression ConvertReturnValue<TInput>(Expression<Func<TInput, object>> inputExpression, Type returnType)
{
    Expression convertedExpressionBody = Expression.Convert(inputExpression.Body, returnType);

    return Expression.Lambda(convertedExpressionBody, inputExpression.Parameters);
}

The above still returns an Expression<Func<TInput, TReturn>> (upcast to a non-generic Expression). You can downcast it later if you need to:

Expression<Func<TDocument, object>> inputExpression = d => d.Name;

Expression<Func<TDocument, string>> convertedExpression
    = (Expression<Func<TDocument, string>>)ConvertReturnValue(inputExpression, typeof(string));

// Test.
TDocument doc = new TDocument { Name = "Zzz" };
string name = convertedExpression.Compile().Invoke(doc);

Assert.Equal("Zzz", name);

Addendum

Note that for struct return types, the final expression may end up looking like this:

(TDocument d) => (int)(object)d.ID;

这篇关于转换表达&lt; Func&lt; TDocument,object&gt;&gt;表达&lt;功能&lt; TDocument,TOutput&gt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆