如何在C#中将字符串数组解构为Serilog的日志参数传入
解决Serilog数组参数未被解构的问题
问题原因
你直接调用的ILogger.Log基础重载不支持将数组解构为多个模板参数,它会把传入的数组当作单个TState对象处理,导致第一个占位符匹配整个数组,后续占位符因无对应参数保留原样。
解决方案
方案1:元素数量固定时直接传递单个参数(最简单)
如果元素数量确定,直接将列表中的每个元素作为独立参数传入Serilog的扩展方法(如LogInformation):
var message = "Age: {Age}, Weight: {Weight}"; var elements = new List<string>{"15yo","60kgs"}; logger.LogInformation(message, elements[0], elements[1]);
方案2:动态参数场景用反射调用扩展方法
当元素数量不固定时,通过反射调用LogInformation扩展方法,将数组元素拆分为独立参数传递:
using System.Reflection; using Serilog; var message = "Age: {Age}, Weight: {Weight}"; var elements = new List<string>{"15yo","60kgs"}; // 获取LogInformation扩展方法的引用 var logMethod = typeof(LoggerExtensions).GetMethod( nameof(LoggerExtensions.LogInformation), new[] { typeof(ILogger), typeof(string), typeof(object[]) }); // 构造调用参数,将元素列表转为object[]作为参数数组 var invokeArgs = new object[] { logger, message, elements.Cast<object>().ToArray() }; // 执行日志记录 logMethod?.Invoke(null, invokeArgs);
方案3:手动构造消息模板状态(底层实现方式)
通过解析消息模板并绑定对应属性,构造Serilog所需的TState对象后调用基础Log方法:
using Serilog; using Serilog.Parsing; using Serilog.Core; var message = "Age: {Age}, Weight: {Weight}"; var elements = new List<string>{"15yo","60kgs"}; // 解析消息模板 var template = new MessageTemplateParser().Parse(message); // 匹配模板属性与元素值 var properties = template.Tokens .OfType<PropertyToken>() .Zip(elements, (token, value) => new MessageTemplateProperty(token.PropertyName, value)) .ToList(); // 创建模板状态对象 var state = new MessageTemplateState(template, properties); // 调用Log方法完成日志输出 logger.Log(LogLevel.Information, new EventId(), state, null, MessageTemplateState.Formatter);
内容的提问来源于stack exchange,提问作者ben
相关产品推荐
相关产品推荐

