[英]C# Expression tree for string interpolation
我有一個程序可以讀取 json 文件,其中包含某個 class 的一些屬性名稱。 配置的屬性名稱的值應該組成一個鍵。
舉個例子:
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",
};
配置文件:
{
"Properties": ["PropertyOne", "PropertyTwo"]
}
如果我在編譯時知道屬性,我將創建一個 lambda ,例如:
Func<SomeClass, string> keyFactory = x => $"{x.PropertyOne}|{x.PropertoTwo}"
有沒有辦法使用表達式編譯這樣的 lambda ? 或者任何其他建議?
在表達式樹中,字符串插值被轉換為string.Format
。 您的樣品的類似物將是:
Func<SomeClass, string> keyFactory =
x => string.Format("{0}|{1}", x.PropertyOne, x.PropertoTwo);
以下 function 動態創建了這樣的委托:
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;
}
用法:
var keyFactory = GenerateKeyFactory<SomeClass>(new[] { "PropertyOne", "PropertyTwo", "PropertyThree" });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.