I have a program that reads a json file with some property names of a certain class. The values of the configured property names should compose up a key.
Lets take an example:
Class:
class SomeClass
{
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public string PropertyThree { get; set; }
public string PropertyFour { get; set; }
}
var someClass = new SomeClass
{
PropertyOne = "Value1",
PropertyTwo = "Value2",
PropertyThree = "Value3",
PropertyFour = "Value4",
};
Configuration file:
{
"Properties": ["PropertyOne", "PropertyTwo"]
}
If I knew the properties at compile time I would have create a lambda like:
Func<SomeClass, string> keyFactory = x => $"{x.PropertyOne}|{x.PropertoTwo}"
Is there a way to compile such a lambda using expressions? Or any other suggestions maybe?
In Expression Tree, string interpolation is converted to string.Format
. Analogue of your sample will be:
Func<SomeClass, string> keyFactory =
x => string.Format("{0}|{1}", x.PropertyOne, x.PropertoTwo);
The following function created such delegate dynamically:
private static MethodInfo _fromatMethodInfo = typeof(string).GetMethod(nameof(string.Format), new Type[] { typeof(string), typeof(object[]) });
public static Func<T, string> GenerateKeyFactory<T>(IEnumerable<string> propertyNames)
{
var entityParam = Expression.Parameter(typeof(T), "e");
var args = propertyNames.Select(p => (Expression)Expression.PropertyOrField(entityParam, p))
.ToList();
var formatStr = string.Join('|', args.Select((_, idx) => $"{{{idx}}}"));
var argsParam = Expression.NewArrayInit(typeof(object), args);
var body = Expression.Call(_fromatMethodInfo, Expression.Constant(formatStr), argsParam);
var lambda = Expression.Lambda<Func<T, string>>(body, entityParam);
var compiled = lambda.Compile();
return compiled;
}
Usage:
var keyFactory = GenerateKeyFactory<SomeClass>(new[] { "PropertyOne", "PropertyTwo", "PropertyThree" });
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.