【问题标题】:C# - Better way to pass in <key, value> pairs to create JProperty objectsC# - 传递 <key, value> 对以创建 JProperty 对象的更好方法
【发布时间】:2021-01-21 19:05:16
【问题描述】:

我的 log4net 对象看起来像这样(因为我想将我的集合记录为 json 对象)

_log.Debug(new JObject(new JProperty("Prop1", "Val1"),
                       new JProperty("Prop2", "Val2")).ToString());       

为了更好的代码可读性和轻松添加其他属性,我想做这样的事情

Utility.WriteLog({"Prop1", "Val1"}, 
                 {"Prop2", "Val2"});

我不确定 WriteLog() 方法的外观如何,除了它应该有一个 params 参数,因为需要记录的属性/值对的数量是可变的。

我考虑了一个字典(见下文),WriteLog 函数将使用字典中的属性/值键创建一个 JsonObject:

Utility.WriteLog(new Dictionary<string, string>()
                        {
                            {"Prop1", "Val1"}, 
                            {"Prop2", "Val2" }
                        });

这是最好的方法,还是有更简洁的替代方法?

【问题讨论】:

  • 你用的是什么版本的c#?
  • 你的初始版本有什么问题?
  • 如果您使用的是 c# 7.0 或更高版本,您可以使用缩写的元组语法,例如public static void WriteLog(params (string Name, object Value) [] parameters) 然后像 Utility.WriteLog(("Prop1", "Val1"), ("Prop2", "Val2")); 一样调用它。见dotnetfiddle.net/cxRnmY。那是你要的吗?你的问题有点主观。
  • 而在 c# 9.0 中,您可以使用 new () { {"Prop1", "Val1"}, {"Prop2", "Val2" } } 来构建您的字典。再次查看dotnetfiddle.net/cxRnmY
  • @Alejandro - 如果你的意思是新的 JProperty() 调用,它就是实例化一个 JObject 并为每个日志记录步骤添加 JProperty 值。

标签: c# json json.net log4net


【解决方案1】:

如果您使用的是 c# 7.0 或更高版本,则可以使用 simplified tuple syntax 传入名称/值 tuplesparams 数组,以便通过序列化和后续日志记录进行格式化。

由于您已标记您的问题,您可以像这样在ILog 上定义扩展方法:

public static partial class LogExtensions
{
    public static void DebugProperties(this ILog log, params (string Name, object Value) [] parameters)
        // TODO: handle duplicate Name keys in some graceful manner.
        => log.Debug(JsonConvert.SerializeObject(parameters.ToDictionary(p => p.Name, p => p.Value), Formatting.Indented));
    
    public static void InfoProperties(this ILog log, params (string Name, object Value) [] parameters)
        => log.Info(JsonConvert.SerializeObject(parameters.ToDictionary(p => p.Name, p => p.Value), Formatting.Indented));
}

然后像这样称呼他们:

log.DebugProperties(("Prop1", "Val1"), ("Prop2", "Val2"));
log.InfoProperties(("Prop3", new SomeClass { SomeValue = "hello" }));

并得到输出:

2021-01-21 21:12:36,215 DEBUG: {
  "Prop1": "Val1",
  "Prop2": "Val2"
}
2021-01-21 21:12:36,230 INFO : {
  "Prop3": {
    "SomeValue": "hello"
  }
}

如果您使用的是 c# 9.0 或更高版本,您还可以添加一个采用 Dictionary&lt;string, object&gt; 的日志记录方法,并在调用该方法时使用 abbreviated new () syntax,它会在已知类型时省略该类型:

public static partial class LogExtensions
{
    public static void DebugDictionary(this ILog log, Dictionary<string, object> parameters)
        => log.Debug(JsonConvert.SerializeObject(parameters, Formatting.Indented));
}

然后:

log.DebugDictionary(new () { {"Prop1", "Val1"}, {"Prop2", "Val2" } } );

当然,如果您愿意,可以将 ILog log 包装在 Utility 类中,其方法的输入类似于上述扩展方法,但如果您使用扩展方法,则没有必要。

演示小提琴here.

【讨论】:

    猜你喜欢
    • 2015-01-23
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多