Thursday, April 3, 2008

"Signature of the body and declaration in a method implementation do not match"

Whilst teaching somebody about unit testing and particular mocking, I came across an error with some code that said, "Signature of the body and declaration in a method implementation do not match".

This seemed like quite a bizarre error message, and worried me, since there wasn't anything immediately obvious as being a problem.

After looking into the problem for a while, there was no help on the net for it, and a whole lot of 'binary search commenting', I tracked the problem down to being a class that had a generic method.

The lights came on! The problem it seems is that whilst in the code it wasn't changing, it was entirely possible for subsequent calls to the generic method to pass different types to that method, thus affecting the method signature.

There's a simple solution, it is to make the whole class have the generic type on it instead, so for the lifetime of the class instance, it can only ever serve up objects on one type only.

Here's a small snippet of code:

What we had first:

public class GenericFactory
{
public objectType Create<objectType>(fullTypeName)
{
.
.
}
}

changes to:

public class GenericFactory<objectType>
{
public objectType Create(fullTypeName)
{
.
.
}
}

Nice and easy, since it is a bizarre error, I hope it helps some people out there. Beware of generics, unless you really understand what you're doing with them!

Martin Platt.

4 comments:

sliderhouserules said...

Uhh... am I daft, or are your before/after code snippets exactly the same?

Mike said...

You're not daft, the angle brackets were interpreted as html elements and didn't show. What you should see is:

What we had first:

public class GenericFactory
{
  public objectType Create<objectType>(fullTypeName)
  {
    .
    .
  }
}

changes to:

public class GenericFactory<objectType>
{
  public objectType Create(fullTypeName)
  {
    .
    .
  }
}

Martin Platt said...

Thanks for the heads up there guys. Fixed now...

Phillip Givens said...

"The problem it seems is that whilst in the code it wasn't changing, it was entirely possible for subsequent calls to the generic method to pass different types to that method, thus affecting the method signature."Could you elaborate? From this description, it doesn't look like you found the problem, just a work around. With generic methods, shouldn't you be able to call the same method with a plethora of different types?

It is not like it locks the method down once it is used. It just creates a concrete version of it.