[英]Combining CallerMemberName with params
现在(C# 4.0)我们的日志记录方法看起来像
public void Log(string methodName, string messageFormat, params object[] messageParameters)
记录器进行字符串格式化的地方,因此调用者没有放置 String.Format 来创建一个不错的日志消息(如果没有附加日志查看器,则允许记录器跳过字符串格式)。
在 c# 5.0 中,我想通过使用新的 CallerMemberName 属性来摆脱 methodName 参数,但我不知道如何将其与 'params' 关键字结合使用。 有没有办法做到这一点?
你可以这样做:
protected static object[] Args(params object[] args)
{
return args;
}
protected void Log(string message, object[] args = null, [CallerMemberName] string method = "")
{
// Log
}
要使用日志,请执行以下操作:
Log("My formatted message a1 = {0}, a2 = {2}", Args(10, "Nice"));
我相信您根本无法将CallerMemberName
所需的params
和可选参数结合起来。 您能做的最好的事情是使用实际数组而不是params
。
以@guilhermekmelo 的回答为基础,我可能建议使用链式方法:
所以保持你当前的Log(string,string,object[]
方法:
public void Log(string methodName, string messageFormat, params object[] messageParameters)
并添加这个新的重载( Log(string,string)
):
public LogMessageBuilder Log(string messageFormat, [CallerMemberName] string methodName = null)
{
// Where `this.Log` is
return new LogMessageBuilder( format: messageFormat, logAction: this.Log );
}
public struct LogMessageBuilder
{
private readonly String format;
private readonly String callerName;
private readonly Action<String,String,Object[]> logAction;
public LogMessageBuilder( String format, String callerName, Action<String,String,Object[]> logAction )
{
this.format = format;
this.callerName = callerName;
this.logAction = logAction;
}
public void Values( params Object[] values )
{
this.logAction( this.format, this.callerName, values );
}
}
像这样使用:
this.Log( "My formatted message a1 = {0}, a2 = {2}" ).Values( 10, "Nice" );
请注意, LogMessageBuilder
是一个struct
,因此它是一个值类型,这意味着它不会导致另一个 GC 分配 - 尽管使用params Object[]
将导致调用站点的数组分配。 (我希望 C# 和 .NET 支持基于堆栈的可变参数,而不是用堆分配的参数数组来伪造它)。
另一种选择是使用FormattableString
- 但请注意,由于 C# 编译器如何为FormattableString
内置特殊情况魔术,您需要小心不要让它被隐式转换为String
(也很糟糕,您无法添加直接扩展到FormattableString
的方法,抱怨):
public void Log(FormattableString fs, [CallerMemberName] string methodName = null)
{
this.Log( messageFormat: fs.Format, methodName: methodName, messageParameters: fs.GetArguments() );
}
用法:
this.Log( $"My formatted message a1 = {10}, a2 = {"Nice"}" );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.