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