How to get Property Wert von MemberExpression ohne .Compile()?

Habe ich Probleme, versuchen, den Wert eines Objekts aus dem Expression Tree ohne Verwendung .Compile()

Das Objekt ist ganz einfach.

var userModel = new UserModel { Email = "[email protected]"};

Die Methode geben wird, mich zu Fragen, wie es aussieht.

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);
    }
}

Den tests, die ich laufen gehe, sind Recht einfach

[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 = "[email protected]"};

    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 );
}

Sollte ich beachten Sie, dass änderungen

var val = (expression.Member as FieldInfo).GetValue((expression.Expression as ConstantExpression).Value);

zu

var val = Expression.Lambda( expression ).Compile().DynamicInvoke().ToString();

erlauben wird, den test zu bestehen, aber diesen code ausführen muss, um auf iOS, und kann daher nicht verwenden .Compile()

  • Ist UserModel.Email wirklich ein Feld? Oder ist es eine Eigenschaft?
  • Wenn es eine Eigenschaft dann expression ist PropertyExpression -> FieldExpression -> ConstantExpression, wenn der code übernimmt nur FieldExpression -> ConstantExpression-daher das problem.
  • Ah, das macht Sinn... laß mich sehen, was ich mit kommen.
  • danke @svick, du hast Recht. Es stolpert auf dem Feld, wenn es tatsächlich eine Eigenschaft.
  • das war ein Abenteuer in Geduld, um den Wert einer Immobilie. Es ist nicht annähernd so intuitiv wie ein Feld.
Schreibe einen Kommentar