首页 > 解决方案 > 由于内联,如何不丢失堆栈跟踪中的方法属性?

问题描述

我想在一个方法上使用一个属性来为调用链中的另一个方法提供信息。我通过检查堆栈跟踪来做到这一点。我的实验结果表明,携带属性的方法可以内联,属性会丢失。

我要求以优雅的方式编写代码,以添加属性并同时防止丢失该属性,即使代价是不内联携带该属性的方法。

我知道我可以MethodImpl(MethodImplOptions.NoInlining)与我的自定义属性一起使用以确保安全,但我不想这样做,因为该属性在许多地方都使用过,它会是“手动耦合”,因此容易出错。

我不知道预处理器宏是否是优雅的解决方案?能否在整个项目中轻松共享?

这个对另一个问题的回答中,我找到了编写一个 Roslyn 插件来为我做这件事的想法。我想避免这种情况,但这可能是迄今为止最优雅的解决方案。

我有一个关于我的属性继承的想法MethodImpl,但那是可悲的sealed

这是我正在试验的最小示例。

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
sealed class A : Attribute { }

static void Main(string[] args)
{
    M();
}

[A]
static void M()
{
    PrintStack();
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void PrintStack()
{
    foreach (var frame in new StackTrace().GetFrames())
    {
        var method = frame.GetMethod();
        Console.WriteLine($"{method.Name} ({method.GetCustomAttributes(true).FirstOrDefault()?.GetType().Name})");
    }
}

在调试版本中,它打印:

PrintStack ()
M (A)
Main ()

在发布版本中,它打印:

PrintStack ()
Main ()

我正在寻找一种解决方案,既可以保留整M (A)行,也可以至少保留A某处的属性(可能在Main方法上)。

标签: c#.net

解决方案


推荐阅读