When exceptions occur during the execution of an application, the stack trace contains the detailed location of where the exception is originated. And for a properly designed application (e.g. all exceptions are properly propagated), this information is adequate. However, some applications need the logging of information not only when exception occurs but along its critical execution path as well. As a result, I see a lot of programs having the location information (for example class names and function names, etc.) hard coded where logging is taken place. This approach, however, tends to introduce inconsistencies over time as the application is modified by many different developers and sometimes the changes to function or class names are not in sync with what is being logged.

This problem can be easily circumvented by using reflections. The following code snippet demonstrates how the current function’s fully qualified name can be obtained using reflection:

                Type t = this.GetType();
 
                string aName = t.FullName;
                string mName = MethodBase.GetCurrentMethod().Name;
                Console.WriteLine(string.Format("{0}.{1}", aName, mName));

And reflection can also be used to obtain the values of member fields (e.g. public and private, etc.):

                Type t = this.GetType();
                FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
 
                foreach (FieldInfo field in fields)
                {
                    string fieldValue = String.Concat(field.Name, ": ", field.GetValue(this).ToString());
                    Console.WriteLine(fieldValue);
                }

This is particularly helpful when logging exceptions, as the member variables’ states would be preserved and it might provide valuable information in determining the causes of the exceptions.

We need to be careful where we use the techniques mentioned above however, as reflection typically comes with pretty hefty performance penalties and thus must be used sparsely where logging is absolutely needed. When reflection is used within the exception catching block, performance is usually not a concern. But we must pay attention to ensure not to cause further exceptions within the exception handling code.

Be Sociable, Share!