首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结合CallerMemberName和params

结合CallerMemberName和params
EN

Stack Overflow用户
提问于 2013-01-16 17:56:23
回答 3查看 6.1K关注 0票数 32

现在(C# 4.0),我们的日志方法看起来像这样

代码语言:javascript
复制
public void Log(string methodName, string messageFormat, params object[] messageParameters)

其中记录器执行字符串格式化,以便调用者不必将String.Format放入以创建良好的日志消息(并允许记录器跳过字符串格式化(如果没有附加日志查看器))。

在C# 5.0中,我希望通过使用新的CallerMemberName属性来摆脱methodName参数,但我不知道如何将其与'params‘关键字结合使用。有没有办法做到这一点?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-16 22:12:22

我认为您不能简单地将CallerMemberName所需的params和可选参数组合在一起。你能做的最好的就是使用实际的数组而不是params

票数 21
EN

Stack Overflow用户

发布于 2014-09-30 22:18:42

你可以这样做:

代码语言:javascript
复制
protected static object[] Args(params object[] args)
{
    return args;
}

protected void Log(string message, object[] args = null, [CallerMemberName] string method = "")
{
    // Log
}

要使用该日志,请执行以下操作:

代码语言:javascript
复制
Log("My formatted message a1 = {0}, a2 = {2}", Args(10, "Nice"));
票数 43
EN

Stack Overflow用户

发布于 2021-04-22 12:17:55

为了构建@guilhermekmelo的答案,我可能会建议使用链式方法:

因此,请保留当前的Log(string,string,object[]方法:

代码语言:javascript
复制
public void Log(string methodName, string messageFormat, params object[] messageParameters)

并添加这个新的重载(Log(string,string)):

代码语言:javascript
复制
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 );
    }
}

如下所示:

代码语言:javascript
复制
this.Log( "My formatted message a1 = {0}, a2 = {2}" ).Values( 10, "Nice" );

请注意,LogMessageBuilder是一个struct,所以它是一个值类型,这意味着它不会导致另一个GC分配-尽管使用params Object[]将导致在调用点进行数组分配。(我希望C#和.NET支持基于堆栈的可变参数,而不是使用堆分配的参数数组来伪造它)。

另一种选择是使用FormattableString -但请注意,由于C# compiler has built-in special-case magic对于FormattableString的方式,您需要小心不要将其隐式转换为String (也很糟糕,您不能直接向FormattableString添加扩展方法,抱怨):

代码语言:javascript
复制
public void Log(FormattableString fs, [CallerMemberName] string methodName = null)
{
    
    this.Log( messageFormat: fs.Format, methodName: methodName, messageParameters: fs.GetArguments() );
}

用法:

代码语言:javascript
复制
this.Log( $"My formatted message a1 = {10}, a2 = {"Nice"}" );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14355600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档