Home > Software design >  C# Make Assert Print Expression Being Asserted
C# Make Assert Print Expression Being Asserted

Time:02-08

When Debug.Assert fails, it shows a very unhelpful error: Assertion failed

This can be improved to get at least some information about the location of the error, like function name, file, and line number like this:

public static void MyAssert(bool expr,
    [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
    [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
    [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
    string message = $"Assertion failed in {memberName} ({sourceFilePath}:{sourceLineNumber})";
    Debug.Assert(expr, message);
}

This helps, but what would be really cool was to be able to see the expression the caller wanted to assert, something like this:

public static void MyAssert(bool expr,
    [PreviousCallerArgumentAsString] string argument)  /* wish this worked */
{
    string message = $"Assertion '{argument}' failed";
    Debug.Assert(expr, message);
}

I am just transitioning to C# but in C this could be done using a macro like this:

#define ASSERT(Expr) Debug.Assert(Expr, "Assertion " #Expr " failed.")

ASSERT(1   1 == 3);
/* would expand to */
Debug.Assert(1   1 == 3, "Assertion 1   1 == 3 failed.");

In my code, I use asserts pretty liberally and having to retype the expression slows you down a ton.

Is there a way something like this could be achieved in C#?

CodePudding user response:

You're in luck! This functionality was implemented in C# 10, using [CallerArgumentExpression].

For example:

public static class Debug
{
    public static void Assert(bool condition, [CallerArgumentExpression("condition")] string message = null)
    {
        if (!condition)
        {
            Console.WriteLine($"Assert failed! {message}");
        }
    }
}

When used with:

Debug.Assert(true == false);

Prints:

Assert failed! true == false

See it on SharpLab.

  •  Tags:  
  • Related