Jul 8 2008

Visual Studio Addin - No such interface supported

Category: .Net | My SoftwareRory Primrose @ 11:00

I'm working on a new Visual Studio addin that launches a profiling application that in turn runs unit and load tests. I can't recall how I created the project, but it must not have been by using the addin wizard. When I debugged the addin in another instance of Visual Studio, I got an error indicating that the addin couldn't be loaded or threw an exception. The additional information it gave was "No such interface supported".

After pulling my hair out for quite a while, the answer was that the AssemblyInfo.cs contained the following:

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

Visual Studio is written mostly in the COM world, including the functionality that resolves and loads addins. This attribute hides the addin from Visual Studio. It therefore can't find the interface it is expecting when it attempts to load the addin from the configured type information. Removing this attribute from AssemblyInfo.cs (it is included by default) or setting its value to true will allow Visual Studio to correctly load the addin.

Tags:

Jul 6 2008

Neovolve ReSharper Plugins 1.0 released

Category: .Net | My Software | ApplicationsRory Primrose @ 10:42

I have just released the ReSharper Plugins 1.0 in my NeovolveX extensibility project on CodePlex. This plugin formats code as part of the ReSharper code format profiles.

The following is a copy of the Using ReSharper Plugins 1.0 documentation on the project site

Value Type Alias Formatter

The ReSharper Plugins project currently contains a single plugin that provides C# code formatting functionality. This formatting function allows for type declarations to be formatted between their alias type and their CLR type. For example, depending of the format settings defined in a code cleanup profile, bool can be converted to Boolean or Boolean converted to bool.

Configuration

The following displays the normal code format profile dialog.

ProfileSettings.jpg

When the plugin is installed, the code format profile dialog will include an additional format option called Type alias conversion.

CustomFormatProfile.jpg

The type conversion options are:
  • Do not change - No change is made to the code
  • Convert to alias type - References of CLR types are converted to their alias types (Boolean to bool for example)
  • Convert from alias type - References of alias types are converted to their CLR types (bool to Boolean for example)
The Do not change setting is the default value.

Type mappings

The following are the type mappings that are supported for converting types between alias types and their CLR types.

Alias type CLR type
object Object
char Char
string String
bool Boolean
byte Byte
short Int16
int Int32
long Int64
ushort UInt16
uint UInt32
ulong UInt64
double Double
decimal Decimal
float Single
sbyte SByte

Code examples

Code formatted to use alias types

AliasCode.jpg

Code formatted to use CLR types

CLRTypeCode.jpg

Grab it from here.

Tags: ,

Jul 3 2008

Reflection Pop Quiz - Does interface inheritance exist?

Category: .NetRory Primrose @ 09:43

I've written some code that reflections MethodInfo objects from a type using its name and signature. This has been working well and all unit tests have passed, until now.

Consider the following code:

internal interface IBaseInterface
{
    void GetSomething();
}

internal interface IDerivedInterface : IBaseInterface
{
    void DoSomethingElse();
}

Does interface inheritance exist?

Much to my amazement, the answer is no, at least according to reflection. This is completely not what I had assumed.

Does it matter? Normally, probably not. The reason is that most people are dealing with concrete types. As concrete types provide implementations of the methods that are defined by their interfaces, the type correctly returns the expected MethodInfo objects from Type.GetMethods().

Interfaces behave very differently. If you call Type.GetMethods() on IDerivedInterface then you will be missing the methods defined in IBaseInterface. I expected that IDerivedInterface had a base type of IBaseInterface and inherited its methods. I made this assumption because that is the affect that IDerivedInterface has on types that implement it. There is an inheritance behaviour as the concrete type must implement methods for both interfaces.

What is interesting is that IDerivedInterface doesn't have a base type, and Type.GetMethods() doesn't return IBaseInterface methods. IDerivedInterface does however indicate that it implements the IBaseInterface interface.

Now things get a little curly here. An interface that implements an interface doesn't need to provide any implementation (it can't, its an interface) or do anything to satisfy implementing the interface. This makes me think that interfaces neither implement other interfaces, or inherit from them.

Here is the complete source:

using System;
using System.Reflection;
 
namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(String[] args)
        {
            // _______________________________________________________
            //
            // Base Interface test
            // _______________________________________________________
            Type baseInterfaceTest = typeof(IBaseInterface);
 
            // This returns 1 method
            MethodInfo[] baseInterfaceMethods = baseInterfaceTest.GetMethods();
 
            // This returns false
            Boolean baseInterfaceHasBaseClass = baseInterfaceTest.BaseType != null;
 
            // This returns null
            Type[] baseInterfaceInterfaces = baseInterfaceTest.GetInterfaces();
 
            // _______________________________________________________
            //
            // Derived Interface test
            // _______________________________________________________
 
            Type derivedInterfaceTest = typeof(IDerivedInterface);
 
            // This will only return 1 method
            MethodInfo[] derivedInterfaceMethods = derivedInterfaceTest.GetMethods();
 
            // This returns false
            Boolean derivedInterfaceHasBaseClass = derivedInterfaceTest.BaseType != null;
 
            // This returns 1 interface type
            Type[] derivedInterfaceInterfaces = derivedInterfaceTest.GetInterfaces();
 
            // _______________________________________________________
            //
            // Derived Type test
            // _______________________________________________________
 
            Type derivedTypeTest = typeof(DerivedType);
 
            // This will return 2 methods (in addition to the 4 from System.Object)
            MethodInfo[] derivedTypeMethods = derivedTypeTest.GetMethods();
 
            // This will return true (System.Object)
            Boolean derivedTypeHasBaseClass = derivedTypeTest.BaseType != null;
 
            // This returns 2 interface type
            Type[] derivedTypeInterfaces = derivedTypeTest.GetInterfaces();
        }
    }
 
    internal interface IBaseInterface
    {
        void GetSomething();
    }
 
    internal interface IDerivedInterface : IBaseInterface
    {
        void DoSomethingElse();
    }
 
    internal class DerivedType : IDerivedInterface
    {
        public void DoSomethingElse()
        {
        }
 
        public void GetSomething()
        {
        }
    }
}

Tags:

Jul 3 2008

Changing TFS changeset comments

Category: .Net | ApplicationsRory Primrose @ 04:53

I had a bit of a slipup yesterday. I had a set of changes that I was relating to two different work items. I realised that I really should split up the check-in into two check-ins so that the code files are better related to their work items. What I didn't do before checking in both changesets was updating the comments of the check-ins before I committed them.

After realising my mistake, I wondered if I could change the comment of a changeset. Thankfully the answer is yes. After finding the changesets by looking at the history in TFS, I was able to simply adjust the comment to be more appropriate to the changeset and click Save. Simple.

Tags:

Jul 2 2008

foreach vs for

Category: .NetRory Primrose @ 05:31

I've just hit the foreach code coverage issue again in one of my unit tests (see my Code coverage doesn't like foreach loops post). To ensure that my tests were correctly covering all possibilities, I had to change the foreach loop into a for loop and run the test again.

The issue in this case is that the collection object I was referencing was ConfigurationElementCollection which implements ICollection. Unfortunately, this type doesn't expose an indexer property. In order to test the code coverage metrics using a for loop, I first had to create an array of the appropriate length and copy across the items across.

After running the test again, I had 100% code coverage. I have now confirmed that the missing blocks in coverage are a result of the foreach statement rather than an issue with my unit test. Now the question is do I remove the additional code and redundant array copy ? The reasons to convert the code back to the foreach loop are:

  • Cleaner code
    • Less bloat
    • More understandable
  • Code coverage shouldn't define coding style

The second point is guaranteed to get some people in a flap. To be clear, I am not saying that testability shouldn't have a bearing on coding style, I'm saying that code coverage shouldn't define coding style. While this post is about code coverage, I should also point out that code coverage doesn't really mean much by itself. It is just an indicator.

In this case, the unit tests were valid and covered all the angles, so the question is purely whether a code coverage metric is important enough to modify the code.

Another thing also comes to mind. What about performance? By using the array, I have the additional overhead of creating an array and populating it from the ICollection, but then I have the performance gain from not using the IEnumerator invoked by the foreach statement.

A quick test gave me a suitable answer.

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
 
namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(String[] args)
        {
            Collection<String> items = new Collection<String>();
 
            for (Int32 index = 0; index < 10; index++)
            {
                items.Add(Guid.NewGuid().ToString());
            }
 
            Stopwatch watch = new Stopwatch();
            const Int32 Iterations = 10000;
 
            Thread.Sleep(1000);
 
            watch.Start();
 
            for (Int32 index = 0; index < Iterations; index++)
            {
                foreach (String item in items)
                {
                    Debug.WriteLine(item);
                }
            }
 
            watch.Stop();
 
            Console.WriteLine("foreach took {0} ticks", watch.ElapsedTicks);
 
            watch.Reset();
            watch.Start();
 
            for (Int32 index = 0; index < Iterations; index++)
            {
                String[] newItems = new String[items.Count];
 
                items.CopyTo(newItems, 0);
 
                for (Int32 count = 0; count < newItems.Length; count++)
                {
                    Debug.WriteLine(newItems[count]);
                }
            }
 
            watch.Stop();
 
            Console.WriteLine("for took {0} ticks", watch.ElapsedTicks);
 
            Console.ReadKey();
        }
    }
}

Each time I run this test, the for loop runs at 70% of the time of the foreach loop, even with the array copy.

While code coverage by itself is not enough to make me change my coding style, a performance improvement and more accurate code coverage is a good enough reason.

Tags: ,