溫故知新,CSharp遇見調用方信息(CallerInfo),通過Attribute、StackTrace獲取調用方的信息

前言

有時候,想以最少成本的改造去記錄下當前方法調用來自哪個方法,以便獲取一些診斷線索。

image

基於Attribute獲取調用方的信息

internal class MyClass
{
    public void Test()
    {
        Log();
    }

    public void Log
    (
        [CallerFilePath]string callerFilePath = null, 
        [CallerLineNumber]int callerLineNumber = 0, 
        [CallerMemberName]string callerMemberName = null
    )
    {
        // callerFilePath:D:\CodeSpace\learn\LearnLog.Caller.ConsoleApp\MyClass.cs, callerLineNumber:15, callerMemberName:Test
        Console.WriteLine($"callerFilePath:{callerFilePath}, callerLineNumber:{callerLineNumber}, callerMemberName:{callerMemberName}");
    }
}

基於StackTrace獲取調用方的信息

private void LogFatherCallerInfo(int skip = 2)
{
    foreach (var frame in new StackTrace().GetFrames().Skip(skip))
    {
        var methodbase = frame.GetMethod();
        // LearnLog.Caller.ConsoleApp.MyClass.Test
        var fatherCallerInfo = $"{methodbase.DeclaringType.Namespace}.{methodbase.DeclaringType.Name}.{methodbase.Name}";
        Console.WriteLine(fatherCallerInfo);
        break;
    }
}

使用示例

internal class MyClass
{
    public void Test()
    {
        Log();
    }

    public void Log()
    {
        LogFatherCallerInfo();
    }

    private void LogFatherCallerInfo(int skip = 2)
    {
        foreach (var frame in new StackTrace().GetFrames().Skip(skip))
        {
            var methodbase = frame.GetMethod();
            // LearnLog.Caller.ConsoleApp.MyClass.Test
            var fatherCallerInfo = $"{methodbase.DeclaringType.Namespace}.{methodbase.DeclaringType.Name}.{methodbase.Name}";
            Console.WriteLine(fatherCallerInfo);
            break;
        }
    }
}

熟悉MVVM的通知屬性的邏輯童鞋

public abstract class ObservableObject : INotifyPropertyChanged, INotifyPropertyChanging
{
    public event PropertyChangedEventHandler? PropertyChanged;

    public event PropertyChangingEventHandler? PropertyChanging;

    protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected void OnPropertyChanging([CallerMemberName] string? propertyName = null)
    {
        if (!Configuration.IsINotifyPropertyChangingDisabled)
        {
            OnPropertyChanging(new PropertyChangingEventArgs(propertyName));
        }
    }

    protected bool SetProperty<T>([NotNullIfNotNull("newValue")] ref T field, T newValue, [CallerMemberName] string? propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, newValue))
        {
            return false;
        }

        OnPropertyChanging(propertyName);
        field = newValue;
        OnPropertyChanged(propertyName);
        return true;
    }
}

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章