In the last weeks Microsoft has made a series of announcements that will benefit a lot to .NET developers. The first one is the new .NET Reference Source experience. While the http://referencesource.microsoft.com/ site has existed for a while, now it provides new tools to navigate the code like you are used to in Visual Studio (Go To Definition, Find References, etc.). This means that for some scenarios (navigating the code of the .NET Framework assemblies) you don’t need tools such as Reflector .NET or JustDecompile. Of course these tools are still required in many other scenarios, since, for example, the source code of Visual Studio assemblies is not available.
The .NET Reference Source provides also these benefits:
- You can download the code in a .zip file for off-line browsing.
- You don’t need a Windows computer to browse the code. A tablet or even a smartphone will work.
- You have the comments of the source code. Not just the headers, which are
useless, but the ones inside the methods explaining why some things are
done in some way (how a bug was fixed, etc.).
For example, last night I used my iPad to browse a couple of things that I was intrigued about:
Years ago I reported a bug in LadyBug (before Microsoft Connect) in the System.Drawing.Color.Equals method. The bug report is no longer available but I remembered that it was related to a comparison of two names that always returned true because the name variable was the same. And yesterday I found it is still there:
public override bool Equals(object obj) { if (obj is Color) { Color right = (Color)obj; if (value == right.value && state == right.state && knownColor == right.knownColor) { if (name == right.name) { return true; } if (name == (object) null || right.name == (object) null) { return false; } return name.Equals(name); } } return false; }
The second one is a tough problem that I was dealing with lately involving COM Reflection (not .NET Reflection). The problem is, given a COM object, how to know its class name (not its interface name). I knew that VB.NET (like VB6 before) has a handy Information.TypeName() method in the Microsoft.VisualBasic assembly, which always seems to return a class name instead of an interface name. Browsing its implementation, I realized that the TypeNameOfCOMObject and LegacyTypeNameOfCOMObject methods are cheating cleaning up the type name:
Friend Function LegacyTypeNameOfCOMObject(ByVal VarName As Object, ByVal bThrowException As Boolean) As String Dim Result As String = COMObjectName Try Call (New SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Demand() Catch ex As StackOverflowException Throw ex Catch ex As OutOfMemoryException Throw ex Catch ex As System.Threading.ThreadAbortException Throw ex Catch e As Exception If bThrowException Then Throw e Else GoTo CleanupTypeName End If End Try Dim pTypeInfo As UnsafeNativeMethods.ITypeInfo = Nothing Dim hr As Integer Dim ClassName As String = Nothing Dim DocString As String = Nothing Dim HelpContext As Integer Dim HelpFile As String = Nothing Dim pDispatch As UnsafeNativeMethods.IDispatch = TryCast(VarName, UnsafeNativeMethods.IDispatch) If pDispatch IsNot Nothing Then hr = pDispatch.GetTypeInfo(0, UnsafeNativeMethods.LCID_US_ENGLISH, pTypeInfo) If hr >= 0 Then hr = pTypeInfo.GetDocumentation(-1, ClassName, DocString, HelpContext, HelpFile) If hr >= 0 Then Result = ClassName End If End If End If CleanupTypeName: If Result.Chars(0) = "_"c Then Result = Result.Substring(1) End If Return Result End Function
That is, if the name starts with “_” (which likely means it is an interface), the class name that implements that interface is the same name without that character, which can be true sometimes but definitely not most of the time.