我正在使用C#为Unity3D开发,并认为拥有一个断言函数会很有用。 (在Unity3D中,System.Diagnostics.Debug.Assert
存在,但什么都不做。)
作为主要在C ++中工作的开发人员,我习惯通过预处理器字符串化运算符来断言包含断言表达式的消息。也就是说,如果形式ASSERT(x > 0, "x should not be zero.")
的断言失败,则在运行时消息处显示的消息可以包括文本“x> 0”。我希望能够在C#中做同样的事情。
我知道ConditionalAttribute和DebuggerHiddenAttribute,并且正在使用两者(尽管后者似乎被与Unity捆绑的MonoDevelop的自定义构建忽略)。在搜索此问题的解决方案时,我在System.Runtime.CompilerServices
命名空间中遇到了三个与我正在尝试做的相关的属性:CallerFilePathAttribute,CallerLineNumberAttribute和CallerMemberNameAttribute。 (在我的实现中,我使用System.Diagnostics.StackTrace
代替fNeedFileInfo == true
。)
我想知道是否有任何反射魔法(似乎不太可能)或属性魔法(似乎更有可能),这可以帮助我实现我在C ++中习惯的相同功能。
答案 0 :(得分:6)
如果你传递一个表达式,你可以接近你想要的x > 0
:
[Conditional("DEBUG")]
public static void Assert(Expression<Func<bool>> assertion, string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
bool condition = assertion.Compile()();
if (!condition)
{
string errorMssage = string.Format("Failed assertion in {0} in file {1} line {2}: {3}", memberName, sourceFilePath, sourceLineNumber, assertion.Body.ToString());
throw new AssertionException(message);
}
}
然后您需要将其称为:
Assert(() => x > 0, "x should be greater than 0");