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?
精彩评论