开发者

interface not implemented error when signing C# assembly

I've been trying to sign an assembly and getting this error:

'Utils.Connection' does not implement interface member 'Interfaces.IConnection.BugFactory()'. 'Utils.Connection.BugFactory()' cannot implement 'Interfaces.IConnection.BugFactory()' because it does not have the matching return type of 'ThirdPartyLibrary.BugFactory'.

That error looks like a dirty, dirty lie! In Utils.Connection, I have this method:

public new BugFactory BugFactory()

I don't think the new keyword is the problem because 1) removing it doesn't stop the error and 2) I'm having the same error with another class that implements IConnection that does not use the new keyword. Update: if I use override instead of new, I get this error:

'Utils.Connection.BugFactory()': cannot override because 'ThirdPartyLibrary.ConnectionClass.BugFactory' is not a function

This is because ThirdPartyLibrary.ConnectionClass.BugFactory is a property.

There is only one BugFactory class, so it isn't a problem of the interface requiring a different BugFactory return type than what the method returns. Even if I explicitly mark my method as returning ThirdPartyLibrary.BugFactory, I still get the error when I try to strong-name the Utils DLL.

Could this be the result of ThirdPartyLibrary being an old COM library that is not CLS-compliant? I ha开发者_高级运维ve no control over this library. When I do not try to sign the Utils assembly, I do not get the interface error.

My big question is: how can I sign this assembly?

Edit: here's what IConnection has:

using ThirdPartyLibrary; // The only using statement
namespace Interfaces
{
   public interface IConnection
   {
       ...
       BugFactory BugFactory();
   }
}


I'm still suspicious of the new keyword for this error.

You say "I don't think the new keyword is the problem because 1) removing it doesn't stop the error", but you must bear in mind that if your method hides a base method, the compiler will add a new, even if you don't specify it, unless you explicity specify override instead.

All the explicit new does is to prevent a compiler warning (not an error).

Is there really a method to hide or override at all?

What happens if you specify virtual instead of new on this method. Does it compile? Does it error with "no suitable method found to override?"

[Edit in response to your comment]

I get this error: "'Utils.Connection.BugFactory()': cannot override because 'ThirdPartyLibrary.ConnectionClass.BugFactory' is not a function." The original ThirdPartyLibrary.ConnectionClass.BugFactory is a property.

I suspect this may be the issue. You are overriding a property with a method.

By using the new keyword, you are hiding the old property to anyone that has a reference to your derived class.

By contrast, anyone that has a reference cast as the superclass (the one you are inheriting from), they will see the old property, and not your new method.

Can you give some more code of the superclass (or interface) together with the derived class?

[Edit in response to your comment]

I'm trying to change the interface to have BugFactory be a property instead of a method

The trouble with new is that it seems like a bit of magic, that can let you change argument types and return types, but it is really pure evil.

Instead of changing the types for all consumers of the code, it only does it for consumers that are cast as the overriding new type. This gets you in the horrible position where two consumers to the same instance will see different signatures depending on how they are cast.

See if you can identify the consuming code that is complaining, and have a think around whether more of your code needs to change to support the type changes. Also, is there the possibility that you are trying to do something that is "a bit of a nasty hack"?


Namespace/version problems?

ThirdPartyLibrary.BugFactory might be a different type, if you have two different versions of the 3rd party assembly being referenced somehow: One during compile time and a different one when you sign/verify..


It sounds like you are simply referencing the COM library through the Add Reference dialog. You should probably create a Primary Interop Assembly for the COM library which can be signed. One of the caveats of signing an assembly is that all the assemblies it references must also be signed.

You would normally use the SDK program TlbImp:

TlbImp yourcomlibrary.tlb /primary /keyfile:yourkeyfile.snk /out:yourcomlibrary.dll


What does your IConnection interface look like? It seems like your ThirdPartyLibrary has a BugFactory object and you also have a BugFactory object either in your project or another reference. Did you try changing both the interface and the concrete type to explicity use ThirdPartyLibrary.BugFactory as the return type for that method?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜