WriteLine both expression and the resulting value?

Viewed 43

I often need to log or write values of expression and also something that gives context to that. So for example:

WriteLine($"_managedHandlePtr:{_managedHandlePtr}");
WriteLine($"metadata.GetNative(_ptr, handle):{metadata.GetNative(_ptr, handle)}");

Is it possible to get the original expression from an interpolated string? Something like the below in concept. It would be nice if I could eliminate the stringly part of this but get the same output:

LogExpression($"{_managedHandlePtr}");
LogExprsssion($"{metadata.GetNative(_ptr, handle)}");

// Writes the non-interpolated string expression, a colon, then the evaluated string
void LogExpression(FormattableString formattableString)
{
  Console.WriteLine(${formattableString.GetExpression()}:{formattableString.ToString()});
}

Output:

_managedHandlePtr:213456
metadata.GetNative(_ptr, handle):0xG5DcS4

It would also be fine if it had to include the notation from the original string:

{_managedHandlePtr}:213456
1 Answers

I don't think you can get much more than the types of the arguments of the FormtableString.

static class Program
{
    static void Main(string[] args)
    {
        Number a = new Number(1.0);     // 1.0
        Percent b = new Percent(2.0);   // 2%
        double c = a + b;

        Console.WriteLine(Format($"{a} + {b} = {c}"));
        // Number + Percent = Double : 1 + 2% = 1.02
    }

    static string Format(this FormattableString expression, CultureInfo info = null)
    {
        if (info == null)
        {
            info = CultureInfo.InvariantCulture;
        }
        object[] names = expression.GetArguments().Select((arg) => arg.GetType().Name).ToArray();
        return $"{string.Format(expression.Format, names)} : {expression.ToString(info)}";
    }
}
Related