条件记录的便捷方式

时间:2016-07-20 15:43:11

标签: c#

记录正在占用资源。特别是要创建日志消息。 为了节省运行时资源,我这样做:

if (logFile!=null) Log(logFile, "Some Message "+someMethod());

当不需要记录时,它消除了调用someMethod。

有更方便的方式来编码吗?像

Logger.logger?.Log("Some Message "+someMethod());

记录器是静态类,记录器是委托......不幸的是它在我的VS2012中不起作用。

更新:此问题的主要目的是如何简化代码外观并减少运行时支出。在我的原始方法方法中,如果不需要记录,则不调用someMethod(),但代码保持不变。检查null只是建议的方法,以避免调用额外的方法。

Update2:一些例子:

    public class Example {      
        public class Logger 
            {
                public static void Log(string message)
                {
                    Console.WriteLine(message);
                }
            }

            public static Logger logger;

            public static void Test()
            {
                // has compilation error "Invalid expression term '.'
                logger?.Log("This "+"should "+"be "+"not invoked"); 
                logger = new Logger();
                logger?.Log("This should "+"be logged");
            }
}

1 个答案:

答案 0 :(得分:1)

你可以在静态类中包装null检查吗? 您无需直接致电该代表。

e.g。

public class Logger
{
    public Action<string> LogAction { get;set; }

    public void Log(string message)
    {
        var logAction = LogAction;

        if(logAction != null)
            logAction(message);
    }
}

然后简称为:

Logger.Log("Something happened");

另一个选项是使用Conditional属性。

https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx

除非在构建期间提供了编译符号,否则不会在编译的IL中调用标有该属性的方法。

public static class Logger
{
    public static Action<string> LogAction { get;set; }

    [Conditional("LoggingEnabled")]
    public static void LogConditional(string message)
    {
        var logAction = LogAction;

        if(logAction != null)
            logAction(message);
    }

    public static void Log(string message)
    {
        var logAction = LogAction;

        if(logAction != null)
            logAction(message);
    }
}

Log方法没有条件属性,因此以下代码生成以下IL:

var foo = "foo";
var bar = "bar";

Logger.Log(foo + bar);

IL_0000:  nop         
IL_0001:  ldstr       "foo"
IL_0006:  stloc.0     // foo
IL_0007:  ldstr       "bar"
IL_000C:  stloc.1     // bar
IL_000D:  ldloc.0     // foo
IL_000E:  ldloc.1     // bar
IL_000F:  call        System.String.Concat
IL_0014:  call        UserQuery+Logger.Log
IL_0019:  nop         
IL_001A:  ret  

LogConditional方法确实具有条件属性,并且尚未设置编译器符号,因此以下代码生成以下IL:

var foo = "foo";
var bar = "bar";

Logger.LogConditional(foo + bar);

IL_0000:  nop         
IL_0001:  ldstr       "foo"
IL_0006:  stloc.0     // foo
IL_0007:  ldstr       "bar"
IL_000C:  stloc.1     // bar
IL_000D:  ret 

正如您所见,由于未生成方法调用,因此永远不会执行字符串连接。