获取表示在C#中用作函数参数的表达式的字符串

时间:2013-02-28 22:58:39

标签: c# reflection attributes unity3d assert

我正在使用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 ++中习惯的相同功能。

1 个答案:

答案 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");