我在尝试获取表达式树中对象的值,但不想使用 .Compile() 方法。
这个对象非常简单。
var userModel = new UserModel { Email = "John@Doe.com"};
让我遇到问题的方法如下。
private void VisitMemberAccess(MemberExpression expression, MemberExpression left)
{
var key = left != null ? left.Member.Name : expression.Member.Name;
if (expression.Expression.NodeType.ToString() == "Parameter")
{
// add the string key
_strings.Add(string.Format("[{0}]", key));
}
else
{
// add the string parameter
_strings.Add(string.Format("@{0}", key));
// Potential NullReferenceException
var val = (expression.Member as FieldInfo).GetValue((expression.Expression as ConstantExpression).Value);
// add parameter value
Parameters.Add("@" + key, val);
}
}
我正在运行的测试非常简单。
[Test] // PASS
public void ShouldVisitExpressionByGuidObject ()
{
// Setup
var id = new Guid( "CCAF57D9-88A4-4DCD-87C7-DB875E0D4E66" );
const string expectedString = "[Id] = @Id";
var expectedParameters = new Dictionary<string, object> { { "@Id", id } };
// Execute
var actualExpression = TestExpression<UserModel>( u => u.Id == id );
var actualParameters = actualExpression.Parameters;
var actualString = actualExpression.WhereExpression;
// Test
Assert.AreEqual( expectedString, actualString );
CollectionAssert.AreEquivalent( expectedParameters, actualParameters );
}
[Test] // FAIL [System.NullReferenceException : Object reference not set to an instance of an object.]
public void ShouldVisitExpressionByStringObject ()
{
// Setup
var expectedUser = new UserModel {Email = "john@doe.com"};
const string expectedString = "[Email] = @Email";
var expectedParameters = new Dictionary<string, object> { { "@Email", expectedUser.Email } };
// Execute
var actualExpression = TestExpression<UserModel>( u => u.Email == expectedUser.Email );
var actualParameters = actualExpression.Parameters;
var actualString = actualExpression.WhereExpression;
// Assert
Assert.AreEqual( expectedString, actualString );
CollectionAssert.AreEquivalent( expectedParameters, actualParameters );
}
我应该提醒您,更改
var val = (expression.Member as FieldInfo).GetValue((expression.Expression as ConstantExpression).Value);
to
var val = Expression.Lambda( expression ).Compile().DynamicInvoke().ToString();
这段代码可以通过测试,但是它需要在iOS上运行,因此不能使用.Compile()
方法。
UserModel.Email
真的是一个字段吗?还是一个属性? - svickexpression
就是 PropertyExpression -> FieldExpression -> ConstantExpression,而代码假设只有 FieldExpression -> ConstantExpression,因此出现了问题。 - Jon