The easiest way, considering the class has only two possible fields to filter on, would be to use simple if-else block :
string targetProperty = "name";
string targetValue = "John";
IEnumerable<Person> query = listExample;
if(targetProperty == "name") query = query.Where(x => x.name == targetValue)
else if(targetProperty == "surname") query = query.Where(x => x.surname == targetValue)
var result = query.ToList();
If the actual class has a lot of possible properties/fields to filter on, and you want to avoid too many if-branches, it's time to use Expression
as mentioned in the comment below the question :
string targetProperty = "name";
string targetValue = "John";
var param = Expression.Parameter(typeof(Person), "x");
var body = Expression.Equal(
Expression.PropertyOrField(param, targetProperty),
Expression.Constant(targetValue));
var predicate = Expression.Lambda<Func<Person, bool>>(body, param);
var result = listExample.Where(predicate.Compile()).ToList();
The above codes should build predicate expression equivalent to x => x.name == "John"
(since targetProperty = "name"
and targetValue = "John"
)