Can I get parameter names/values procedurally from the currently executing function?

后端 未结 6 1387
猫巷女王i
猫巷女王i 2020-12-02 14:38

I would like to do something like this:

public MyFunction(int integerParameter, string stringParameter){
    //Do this:
    LogParameters();
    //Instead of         


        
6条回答
  •  醉话见心
    2020-12-02 15:04

    I followed the instructions and created this class:

    public static class Tracer
    {
        public static void Parameters(params object[] parameters)
        {
            #if DEBUG
                var jss = new JavaScriptSerializer();
    
                var stackTrace = new StackTrace();
    
                var paramInfos = stackTrace.GetFrame(1).GetMethod().GetParameters();
    
                var callingMethod = stackTrace.GetFrame(1).GetMethod();
                Debug.WriteLine(string.Format("[Func: {0}", callingMethod.DeclaringType.FullName + "." + callingMethod.Name + "]"));
    
                for (int i = 0; i < paramInfos.Count(); i++)
                {
                    var currentParameterInfo = paramInfos[i];
    
                    var currentParameter = parameters[i];
    
                    Debug.WriteLine(string.Format("    Parameter: {0}", currentParameterInfo.Name));
    
                    Debug.WriteLine(string.Format("    Value: {0}", jss.Serialize(currentParameter)));
                }
                Debug.WriteLine("[End Func]");
            #endif
        }
    }
    

    Call it like this:

    public void Send(T command) where T : Command
    {
        Tracer.Parameters(command);
    }
    

    And the output looks like this

    [Func: SimpleCQRS.FakeBus.Send]
        Parameter: command
        Value: {"InventoryItemId":"f7005197-bd20-42a6-b35a-15a6dcc23c33","Name":"test record"}
    [End Func]
    

    Editing

    .........

    And I extended my tracer function to really do a great job for me. To trace every function and its calling function, etc., you can use StrackTrace.GetFrame(2) to use added functionality. And now my output is much richer. I also used Json.NET's library to output nice looking formatted JSON objects. Also the output can be pasted in an empty JavaScript file and see colorized output.

    Now my output looks like this:

    //Func: HomeController(Constructor): CQRSGui.Controllers.HomeController(Constructor)
    //From: RuntimeTypeHandle.CreateInstance: System.RuntimeTypeHandle.CreateInstance
    var parameters = {}
    
    //Func: HomeController.Add: CQRSGui.Controllers.HomeController.Add
    //From: System.Object lambda_method(System.Runtime.CompilerServices.Closure, System.Web.Mvc.ControllerBase, System.Object[])
    var parameters = {
        "name": "car"
    }
    
    //Func: Command(Constructor): SimpleCQRS.Command(Constructor)
    //From: CreateInventoryItem(Constructor): SimpleCQRS.CreateInventoryItem(Constructor)
    var parameters = {}
    
    //Func: CreateInventoryItem(Constructor): SimpleCQRS.CreateInventoryItem(Constructor)
    //From: HomeController.Add: CQRSGui.Controllers.HomeController.Add
    var parameters = {
        "inventoryItemId": "d974cd27-430d-4b22-ad9d-22ea0e6a2559",
        "name": "car"
    }
    
    //Func: FakeBus.Send: SimpleCQRS.FakeBus.Send
    //From: HomeController.Add: CQRSGui.Controllers.HomeController.Add
    var parameters = {
        "command": {
            "InventoryItemId": "d974cd27-430d-4b22-ad9d-22ea0e6a2559",
            "Name": "car"
        }
    }
    
    //Func: InventoryCommandHandlers.Handle: SimpleCQRS.InventoryCommandHandlers.Handle
    //From: FakeBus.Send: SimpleCQRS.FakeBus.Send
    var parameters = {
        "message": {
            "InventoryItemId": "d974cd27-430d-4b22-ad9d-22ea0e6a2559",
            "Name": "car"
        }
    }
    
    //Func: AggregateRoot(Constructor): SimpleCQRS.AggregateRoot(Constructor)
    //From: InventoryItem(Constructor): SimpleCQRS.InventoryItem(Constructor)
    var parameters = {}
    
    //Func: InventoryItem(Constructor): SimpleCQRS.InventoryItem(Constructor)
    //From: InventoryCommandHandlers.Handle: SimpleCQRS.InventoryCommandHandlers.Handle
    var parameters = {
        "id": "d974cd27-430d-4b22-ad9d-22ea0e6a2559",
        "name": "car"
    }
    
    //Func: Event(Constructor): SimpleCQRS.Event(Constructor)
    //From: InventoryItemCreated(Constructor): SimpleCQRS.InventoryItemCreated(Constructor)
    var parameters = {}
    
    //Func: InventoryItemCreated(Constructor): SimpleCQRS.InventoryItemCreated(Constructor)
    //From: InventoryItem(Constructor): SimpleCQRS.InventoryItem(Constructor)
    var parameters = {
        "id": "d974cd27-430d-4b22-ad9d-22ea0e6a2559",
        "name": "car"
    }
    
    //Func: AggregateRoot.ApplyChange: SimpleCQRS.AggregateRoot.ApplyChange
    //From: InventoryItem(Constructor): SimpleCQRS.InventoryItem(Constructor)
    var parameters = {
        "event": {
            "Id": "d974cd27-430d-4b22-ad9d-22ea0e6a2559",
            "Name": "car",
            "Version": 0
        }
    }
    

    Powerful, isn't it? I just need to see the output and don't need to break the application again and again and don't need to check into watch and local windows. I love this way. I have put the tracker.Parameters function in everywhere in my application and I have now automatically debugged the application.

    One thing which I added to my outputting function was a call to Error Event in serialization. And handled that from Json.NET. Actually you can fall into a circular reference error. Which I caught. And also if there are more serialization errors you can catch them and then you can display serialization errors just below the parameters object output.

提交回复
热议问题