在运行时备份stacktrace

时间:2015-03-06 18:59:05

标签: c# debugging constraints

这可能看起来像一个奇怪的问题,但谷歌并没有给我任何东西。

我有一些扩展方法,允许我按需评估返回值等。我在合同不能真正做我想要的地方使用它们。

这些扩展方法的作用是将旧学校Debug.Assert()和一个'用于实现'检查如果不满足条件则抛出异常。我还有其他一些允许你抛出特定异常的东西。例如:

public static void IsNotNullOrEmpty(this System.Collections.ICollection input, string message = default(string), bool throwOnFailure = true)
            {
                if (!string.IsNullOrEmpty(message))
                    Debug.Assert(input != null && input.Count > 0, message);

                if (input == null || input.Count == 0 && throwOnFailure)
                    throw new ArgumentNullException(message);
            }

        public static void IsNotNull<T>(this object input, string message = default(string), bool throwOnFailure = true)  where T : Exception, new()
        {
            if (!string.IsNullOrEmpty(message))
                Debug.Assert(input != null, message);

            if (input == null && throwOnFailure)
            {
                // NOTE - catches the possibility that the Exception class's implementation does not have a constructor that takes a message
                // Have to do it this way because the Message property is readonly on the Exception class so we can't just set it.
                try 
                {
                    throw Activator.CreateInstance(typeof(T), message) as T;
                } 
                catch(MissingMethodException)  
                {
                    throw new T();
                }
            }
        }

他们确实工作得很好。唯一的问题是debug assert将调试器捕捉到Debug.Assert()行。我希望能够捕捉到实际违反约束条件的行。

所以我的问题是,我可以在堆栈跟踪上轻松使用.GetFrame(1)来获取调用约束的方法的MethodInfo。但是如何让VS中的调试器备份一帧并显示该方法,就好像你在callstack窗口中双击它一样?

可能有一种方法可以用Nuget上的一些预先包装的东西来做这件事,或者你有什么,但到目前为止,这些对我有好处。

有人有想法吗?

感谢 ë

2 个答案:

答案 0 :(得分:1)

你想要的是DebuggerStepThroughAttribute

如果在使用此属性标记的方法中抛出异常,则调试器将放置在调用方法的行上,而不是放在方法内。

换句话说,你想要声明你的方法:

[DebuggerStepThrough]
public static void IsNotNullOrEmpty(...)
{
    ...
}

[DebuggerStepThrough]
public static void IsNotNull<T>(...)
    where T : Exception, new()
{
    ...
}

另请注意,如果在调试器中使用step into函数,则不会进入其中一个方法,而是将其作为外部步骤,这将调试这些方法更难。

您可能需要考虑将该属性放在#ifdef...#endig部分中,以便轻松切换到允许您调试它们的配置。

答案 1 :(得分:0)

我只是想知道你是不是这个意思。这将返回调用程序的方法和类的名称。

public static bool IsNull(this string value)
{
    var method = new StackTrace().GetFrame(1).GetMethod();
    Console.WriteLine(String.Format("I was called from '{0}' of class '{1}'", method.Name, method.DeclaringType));

    return string.IsNullOrEmpty(value);
}