簡體   English   中英

C# 用於字符串插值的表達式樹

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM