Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of the () => vs just getting a property directly

Tags:

c#

So I am learning more C# and came across this syntax:

Log.Info(() => $"Some Text {SomeVariableorProperty}");

How does this differ from the following?

Log.Info($"Some Text {SomeVariableorProperty}");

I know that the () => is basically a delegate but not sure what its purpose is here.

like image 252
LTrain Avatar asked Nov 28 '22 06:11

LTrain


1 Answers

The scenario is:

Log.Info(() => $"Some Text {SomeSlowMethod()}");

public static string SomeSlowMethod()
{
    Thread.Sleep(5000);
    return "Foo";
}

Now... What happens if the logging of Info is disabled? Is the SomeSlowMethod called? The answer is no! Because the calling of the delegate () => $"Some Text {SomeSlowMethod()} is done by Log.Info() if it needs to do it. Compare it with:

Log.Info($"Some Text {SomeSlowMethod()}");

Now SomeSlowMethod() is always called, and there is the possibility that Log.Info will ignore its value.

If you think that SomeSlowMethod()s in real case scenarios don't exist, remember that even string composition is "slow" compared to other operations. Simply doing useless string.Format ($"Some Text {SomeVariableorProperty} is a string.Format) is a waste of time. And one of the laws of a good logging library is that if it isn't active it shouldn't slow your application.

To make an interesting comparison, Debug.Assert():

[Conditional("DEBUG")]
public static void Assert(bool condition, string message);

Here message is a string, but you see the [Conditional(...)]? if DEBUG isn't defined at compile time, the C# compiler can remove the whole Debug.Assert() method call, and even remove all the methods that are called inside the Debug.Assert(), so modifying possible side effects:

Debug.Assert(false, Throw());

public static string Throw()
{
    throw new Exception();
}

If DEBUG isn't defined (so you are executing a RELEASE build), this will be converted to:

; // nothing

so no throw (see for example this). But note that this must be resolved at compilation time, while logging libraries are configured at runtime.

like image 113
xanatos Avatar answered Nov 30 '22 19:11

xanatos