Skip to content

Commit

Permalink
Support indexers in expression trees when generating PropertyChain fo…
Browse files Browse the repository at this point in the history
…r simple cases.
  • Loading branch information
JeremySkinner committed Jan 23, 2023
1 parent 781c57c commit 6dfc062
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/FluentValidation.Tests/PropertyChainTests.cs
Expand Up @@ -83,6 +83,13 @@ public class PropertyChainTests {
chain.ToString().ShouldEqual("Address.Id");
}

[Fact]
public void Creates_from_expression_with_indexer() {
Expression<Func<Person, string>> expr = x => x.Orders[0].ProductName;
var chain = PropertyChain.FromExpression(expr);
chain.ToString().ShouldEqual("Orders[0].ProductName");
}

[Fact]
public void Should_ignore_blanks() {
chain.Add("");
Expand Down
23 changes: 21 additions & 2 deletions src/FluentValidation/Internal/PropertyChain.cs
Expand Up @@ -70,10 +70,29 @@ public class PropertyChain {
});

var memberExp = getMemberExp(expression.Body);
string indexer = null;

while(memberExp != null) {
memberNames.Push(memberExp.Member.Name);
memberExp = getMemberExp(memberExp.Expression);
string propertyName = memberExp.Member.Name;

if (indexer != null) {
propertyName += "[" + indexer + "]";
indexer = null;
}

memberNames.Push(propertyName);

// Handle indexers.
if (memberExp.Expression is MethodCallExpression mce) {
if (mce.Method is {IsSpecialName: true, Name: "get_Item"} && mce.Arguments.Count == 1 && mce.Arguments[0] is ConstantExpression ce) {
indexer = ce.Value?.ToString();
memberExp = getMemberExp(mce.Object);
}
}
else {
memberExp = getMemberExp(memberExp.Expression);
}

}

return new PropertyChain(memberNames);
Expand Down

0 comments on commit 6dfc062

Please sign in to comment.