For those who like their asserts plentiful, but do not seeing the same assert over and over during execution.
Note: the displayed stackframe will include asserto.
/// Asserto.cs
/// Copyright (c) 2013 Eric Itomura
///
/// This software is provided 'as-is', without any express or implied
/// warranty. In no event will the authors be held liable for any damages
/// arising from the use of this software.
///
/// Permission is granted to anyone to use this software for any purpose,
/// including commercial applications, and to alter it and redistribute it
/// freely.
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace ProjectB
{
/// <summary>
/// Asserto is an assert wrapper which tracks calls to the same assert
/// and total asserts hit, and will ignore assert calls beyond the specified threshold.
/// </summary>
public class Asserto
{
/// <summary>
/// Total number of asserts to trigger before ignoring all subsequent asserts.
/// </summary>
const int TotalAssertsMax = 1;
/// <summary>
/// Number of asserts to trigger before ignoring subsequent unique asserts.
/// </summary>
const int RepeatUniqueAssertsMax = 1;
static Dictionary<string, int> m_keyAndCount = new Dictionary<string, int>();
static int m_totalAssertCount = 0;
/// <summary>
/// Tracked assert, checks if object is null.
/// </summary>
/// <param name="obj">asserts if obj is null</param>
[Conditional("DEBUG")]
static public void Assert(object obj)
{
Assert(obj!=null, obj+" was null.");
}
/// <summary>
/// Tracked assert with no message.
/// </summary>
/// <param name="cond">conditional will assert if false</param>
[Conditional("DEBUG")]
static public void Assert(bool cond)
{
Assert(cond, "");
}
/// <summary>
/// Tracked assert with message.
/// </summary>
/// <param name="cond">conditional will assert if false</param>
/// <param name="msg">message to display upon assert</param>
[Conditional("DEBUG")]
static public void Assert(bool cond, string msg)
{
if (!cond)
{
var shouldAssert = false;
if (m_totalAssertCount < TotalAssertsMax)
{
StackFrame stack = new StackFrame(1, true);
if (stack != null)
{
string key = stack.GetFileName() != null
? stack.GetFileName().ToString() : "";
key += stack.GetFileLineNumber().ToString();
if (!m_keyAndCount.ContainsKey(key))
{
if (1 <= RepeatUniqueAssertsMax)
{
shouldAssert = true;
m_keyAndCount.Add(key, 1);
}
}
else
{
var count = m_keyAndCount[key];
if (count <= RepeatUniqueAssertsMax)
{
shouldAssert = true;
m_keyAndCount[key] = count + 1;
}
}
}
else
{
shouldAssert = true;
}
if (shouldAssert)
{
Debug.Assert(cond, msg);
++m_totalAssertCount;
}
}
}
}
/// <summary>
/// Flag always asserts upon call with a message.
/// </summary>
/// <param name="msg">message to display when asserting</param>
[Conditional("DEBUG")]
static public void Flag(string msg)
{
bool shouldAssert = false;
if (m_totalAssertCount < TotalAssertsMax)
{
StackFrame stack = new StackFrame(1, true);
if (stack != null)
{
string key = stack.GetFileName() != null
? stack.GetFileName().ToString() : "";
key += stack.GetFileLineNumber().ToString();
if (!m_keyAndCount.ContainsKey(key))
{
if (1 <= RepeatUniqueAssertsMax)
{
shouldAssert = true;
m_keyAndCount.Add(key, 1);
}
}
else
{
var count = m_keyAndCount[key];
if (count <= RepeatUniqueAssertsMax)
{
shouldAssert = true;
m_keyAndCount[key] = count + 1;
}
}
}
else
{
shouldAssert = true;
}
}
if (shouldAssert)
{
Debug.Assert(false, msg);
++m_totalAssertCount;
}
}
/// <summary>
/// Debug printing.
/// </summary>
/// <param name="msg">message to print</param>
[Conditional("DEBUG")]
static public void Print(string msg)
{
Console.Write(msg);
}
}
}