Skip to content

Propriété de recherche dans le graphe d’objet via une chaîne

Solution:

Vous pouvez simplement utiliser la méthode .NET DataBinder.Eval standard, comme ceci :

object result = DataBinder.Eval(myPerson, "PersonsAddress.HousePhone.Number");

J’ai eu à quelque chose de similaire dans le passé. J’ai opté pour l’approche lambda car après les avoir compilés, je peux les mettre en cache. J’ai supprimé la mise en cache dans ce code.

J’ai inclus quelques tests unitaires pour montrer l’utilisation de la méthode. J’espère que ceci est utile.

private static object GetValueForPropertyOrField( object objectThatContainsPropertyName, IEnumerable<string> properties )
  {
     foreach ( var property in properties )
     {
        Type typeOfCurrentObject = objectThatContainsPropertyName.GetType();

        var parameterExpression = Expression.Parameter( typeOfCurrentObject, "obj" );
        Expression memberExpression = Expression.PropertyOrField( parameterExpression, property );

        var expression = Expression.Lambda( Expression.GetDelegateType( typeOfCurrentObject, memberExpression.Type ), memberExpression, parameterExpression ).Compile();

        objectThatContainsPropertyName = expression.DynamicInvoke( objectThatContainsPropertyName );
     }

     return objectThatContainsPropertyName;
  }

  [TestMethod]
  public void TestOneProperty()
  {
     var dateTime = new DateTime();

     var result = GetValueForPropertyOrField( dateTime, new[] { "Day" } );

     Assert.AreEqual( dateTime.Day, result );
  }

  [TestMethod]
  public void TestNestedProperties()
  {
     var dateTime = new DateTime();

     var result = GetValueForPropertyOrField( dateTime,  new[] { "Date", "Day" } );

     Assert.AreEqual( dateTime.Date.Day, result );
  }

  [TestMethod]
  public void TestDifferentNestedProperties()
  {
     var dateTime = new DateTime();

     var result = GetValueForPropertyOrField( dateTime, new[] { "Date", "DayOfWeek" } );

     Assert.AreEqual( dateTime.Date.DayOfWeek, result );
  }

Voici une version non récursive avec (presque) la même sémantique :

private static object ObjectFromString(object basePoint, IEnumerable<string> pathToSearch)
{
    var value = basePoint;
    foreach (var propertyName in pathToSearch)
    {
        var property = value.GetType().GetProperty(propertyName);
        if (property == null) return null;
        value = property.GetValue(value, null);
    }
    return value;
}



Articles Similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.