I love the .NET Framework. I’ve been programming in C# since 2001, I spent much of my free time for a decade building Fiddler on .NET, and I now code in C# for a living. .NET provides a fantastic, highly-productive platform suitable for building a huge range of tools and applications, and as it grows in power and performance, its scope has only grown.
However, there’s one task for which .NET code isn’t suitable: building in-process browser extensions like Toolbars, BHOs, Pluggable Protocols, and ActiveX controls. These COM-based extensibility mechanisms were exposed long before the .NET Framework, and while .NET offers powerful interop with COM, it’s not an appropriate technology to implement browser extensions.
.NET-based browser extensions are responsible for significant performance and reliability problems in the browser. Even now that the .NET Framework version 4 resolved the side-by-side versioning problem, Raymond Chen notes that in-process browser & shell extensions shouldn’t be written in managed code. The Issues Specific to the .NET Framework section of the Guidance for Implementing In-Process Extensions MSDN article explains this topic in further detail.
Of the extension types, Toolbars and BHOs are the most problematic, as they are automatically loaded by every tab upon startup and often perform processing on every page load. The performance impact of such extensions can severely hurt the overall performance of the browser. Managed Pluggable Protocols and ActiveX controls are somewhat less problematic, as they’re only loaded when invoked by web content, but such usage should still be avoided.
Obviously, .NET remains a great choice for out-of-process interaction with browsers (e.g. like Fiddler or applications invoked by Application Protocol url schemes). If necessary, you could even use .NET to do most of the heavy lifting for your BHO or toolbar—just do so by writing a native-code COM extension (using C++, Delphi, etc) that itself uses RPC/named pipes/etc to marshal data to the out-of-process .NET code. That way, the only code running in-process with the browser is native and you avoid loading the framework into the browser process.