我正在尝试将方法转换为表达式树以进行测试,但收到错误
Exception thrown: 'System.ArgumentException' in System.Linq.Expressions.dll Expression of type 'System.Void' cannot be used for return type 'TestDatabase.Models.TestEnum'
同时,我想知道如何获取异常测试输出的输入值。
我尝试重新创建表达式树的原始方法是:
private TEnum ConvertStringToEnum(TDbValueType dbValue)
{
if (Enum.IsDefined(typeof(TEnum), dbValue))
{
return (TEnum)Enum.Parse(typeof(TEnum), (string)(object)dbValue);
}
throw new Exception("");
}
表达式树构建方法是
public static Func<TString, TEnum> BuildStringToEnumConvertor<TString, TEnum>()
{
var enumType = typeof(TEnum);
var enumTypeExp = Expression.Constant(enumType);
//var labeleExp = Expression.Label(enumType);
var dbValueExp = Expression.Parameter(typeof(TString), "dbValue");
var m = typeof(Enum).GetMethod("IsDefined", [typeof(Type), typeof(object)]);
//test
var testExp = Expression.Call(null, m, enumTypeExp, dbValueExp);
//true
var objExp = Expression.Convert(dbValueExp, typeof(object));
var strExp = Expression.Convert(objExp, typeof(string));
m = typeof(Enum).GetMethod("Parse", [typeof(Type), typeof(string)]);
var retExp = Expression.Call(null, m, enumTypeExp, strExp);
objExp = Expression.Convert(retExp, enumType);
//var returnExp = Expression.Return(labeleExp, objExp);
//false
//var x = Expression.Lambda<Func<string>>(dbValueExp).CompileFast();
//var x = Expression.Lambda<Func<string>>(dbValueExp).Compile();
var falseExp = Expression.Throw(Expression.Constant(new Exception($"could not convert \" {{how to get the input parameter value ??}} \" to type \"{typeof(TEnum).Name}\".")));
var xxExp = Expression.IfThenElse(testExp, objExp, falseExp);
//var block = Expression.Block(objExp, falseExp);
//return Expression.Lambda<Func<TString, TEnum>>(block, dbValueExp).CompileFast();
return Expression.Lambda<Func<TString, TEnum>>(xxExp, dbValueExp).Compile(); <-- error here
}
internal enum TestEnum
{
Age = 1,
Name,
Address,
CellPhone,
Max = 500
}
当我打电话时var func = BuildStringToEnumConvertor<string, TestEnum>();
,出现以下异常:
Unhandled exception. System.ArgumentException: Expression of type 'System.Void' cannot be used for return type 'Program+TestEnum'
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters, String paramName)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
at Program.BuildStringToEnumConvertor[TString,TEnum]()
在此处运行演示: https: //dotnetfiddle.net/IkYEpJ
返回的类型
Expression.IfThenElse
始终为 void,若要指定类型,请使用Expression.Condition
:您还需要为 throw 表达式指定一个类型:
要获取输入参数值,可以手动构造异常对象