October 23, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Whammy Tracing: Hassle-Free .NET Debugging

  • August 7, 2006
  • By Paul Kimmel
  • Send Email »
  • More Articles »

Using Reflection to Obtain Method Information

Reflection is a .NET technology that evolved from run time type information (RTTI). It allows you to explore the .NET metamodel. Reflection supports a very dynamic kind of programming that enables programmers to receive an object blindly and then ask about its methods, fields, properties, and events. You can even invoke these operations or dynamically invoke methods without knowing what they are before hand.

Reflection is a very useful technology that you can use to dynamically resolve the namespace and name of a calling method (the following Whammy class listing shows how). You also could expand the details of the reflected type and make the Whammy output more verbose:

Listing 1: The Whammy Class Automatically Provides Trace Information about the Calling Method

Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Text
Module Module1
   Sub Main()
      Whammy.ConsoleWrite()
      Console.ReadLine()
      System.Diagnostics.Trace.WriteLine("Main called")
   End Sub
End Module
' Thanks to Bill Wagner and Addison Wesley for the StackTrace tip
' in Effective C#
Public Class Whammy
   <Conditional("DEBUG")> _
   Public Shared Sub DebugWrite()
      Debug.WriteLine(GetMyName())
   End Sub
   <Conditional("DEBUG")> _
   Public Shared Sub DebugWriteWithTimeStamp()
      Dim mask As String = String.Format("{0} called at {1}", _
         GetMyName(), DateTime.Now)
      Debug.WriteLine(mask)
   End Sub
   <Conditional("DEBUG")> _
   Public Shared Sub ConsoleWrite()
      Console.WriteLine(GetMyName())
   End Sub
   <Conditional("DEBUG")> _
   Public Shared Sub ConsoleWriteWithTimestamp()
      Dim mask As String = String.Format("{0} called at {1}", _
         GetMyName(), DateTime.Now)
      Console.WriteLine(mask)
   End Sub
   <Conditional("DEBUG")> _
   Public Shared Function GetMyName()
      Dim trace As New StackTrace()
      Try
         Return String.Format("{0}.{1}", _
            trace.GetFrame(2).GetMethod().ReflectedType.FullName, _
            trace.GetFrame(2).GetMethod().Name)
      Catch ex As Exception
         Return String.Format(trace.GetFrame(1).GetMethod().Name)
      End Try
   End Function
End Class

The code is pretty straightforward after you understand how its three key technologies—ConditionalAttribute, Reflection, and StackTrace and StackFrame objects—work. The first statement in bold (Whammy.ConsoleWrite) demonstrates how easy it is to employ the Whammy class. The next statement in bold (ConditionalAttribute("Debug")>) shows the proper usage of the ConditionalAttribute class.

When the class "undefines" DEBUG, the Whammy code is pretty much ignored, which mitigates any costs of using the trace capability after deployment. However, you could use a custom string for this attribute and turn the Whammy back on after deployment if you needed to.

The GetName function in bold demonstrates how you can get a StackTrace and StackFrame. GetMethod returns a MethodInfo object, which tells you about the reflected type, the namespace and class, and the method name. The integer passed to GetFrame tells you which frame you'd like to get: GetFrame(0) gets the method currently in; GetFrame(1) would get any method that called GetMyName; because you want the external caller, you use GetFrame(2).

The output from the sample indicates that the caller was WhammyDemo.Module1.Main, the Main method.

Another .NET Goody

The difference between advanced solutions and a lot of unnecessary work is knowing your tools' capabilities. Six years after first using the very rich, diverse set of tools in .NET, I am still amazed at how many cool technologies, such as reflection, attributes, and stack information, are available.

Acknowledgements

I'd like to offer a special thanks to Bill Wagner and Addison Wesley for letting me borrow the stack trace technique from Bill's excellent book Effective C#.

About the Author

Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his new book UML DeMystified from McGraw-Hill/Osborne. Paul is an architect for Tri-State Hospital Supply Corporation. You may contact him for technology questions at pkimmel@softconcepts.com.

If you are interested in joining or sponsoring a .NET Users Group, check out www.glugnet.org.

Copyright © 2006 by Paul T. Kimmel. All Rights Reserved.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel