签署 C# 程序集时出现接口未实现错误
我一直在尝试签署程序集并收到此错误:
“Utils.Connection”未实现接口成员“Interfaces.IConnection.BugFactory()”。 “Utils.Connection.BugFactory()”无法实现“Interfaces.IConnection.BugFactory()”,因为它没有匹配的“ThirdPartyLibrary.BugFactory”返回类型。
这个错误看起来像是一个肮脏的谎言!在 Utils.Connection
中,我有这个方法:
public new BugFactory BugFactory()
我不认为 new
关键字是问题,因为 1) 删除它并不能阻止错误,2) 我另一个实现 IConnection
的类也有同样的错误,但不使用 new
关键字。 更新:如果我使用override
而不是new
,我会收到以下错误:
“Utils.Connection.BugFactory()”:无法重写,因为“ThirdPartyLibrary.ConnectionClass.BugFactory”不是函数
这是因为 ThirdPartyLibrary.ConnectionClass.BugFactory
是一个属性。
只有一个 BugFactory
类,因此接口需要与方法返回的 BugFactory
返回类型不同的问题并不存在。即使我明确地将我的方法标记为返回 ThirdPartyLibrary.BugFactory
,当我尝试强命名 Utils
DLL 时,我仍然会收到错误。
这可能是由于 ThirdPartyLibrary
是一个不符合 CLS 的旧 COM 库造成的吗?我无法控制这个图书馆。当我不尝试签署Utils
程序集时,我没有收到接口错误。
我的大问题是:我如何签署这个程序集?
编辑:这是IConnection
的内容:
using ThirdPartyLibrary; // The only using statement
namespace Interfaces
{
public interface IConnection
{
...
BugFactory BugFactory();
}
}
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 have 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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我仍然怀疑
new
关键字是否会导致此错误。你说“我不认为 new 关键字是问题,因为 1) 删除它并不能阻止错误”,但你必须记住,如果你的方法隐藏了基本方法,编译器将添加一个
new
,即使您没有指定它,除非您明确指定override
。所有显式的 new 所做的都是为了防止编译器警告(而不是错误)。
真的有隐藏或覆盖的方法吗?
如果您在此方法上指定
virtual
而不是new
,会发生什么情况。它能编译吗?是否会出现“找不到合适的方法来覆盖”的错误?[编辑以回应您的评论]
我怀疑这可能是问题所在。您正在使用方法覆盖属性。
通过使用 new 关键字,您可以向任何引用您的派生类的人隐藏旧属性。
相比之下,任何将引用强制转换为超类(您继承的超类)的人都会看到旧属性,而不是您的新方法。
您能否提供更多超类(或接口)以及派生类的代码?
[编辑以回应您的评论]
麻烦在于它看起来有点神奇,可以让你改变参数类型和返回类型,但它确实是纯粹的邪恶。
它不会更改代码的所有使用者的类型,而是仅对被强制转换为重写新类型的使用者执行此操作。这会让你陷入可怕的境地,同一个实例的两个消费者将看到不同的签名,具体取决于他们的投射方式。
看看您是否可以识别正在抱怨的消费代码,并考虑是否需要更改更多代码以支持类型更改。另外,您是否有可能尝试做一些“有点令人讨厌的黑客行为”?
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 specifyoverride
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 ofnew
on this method. Does it compile? Does it error with "no suitable method found to override?"[Edit in response to your comment]
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]
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"?
命名空间/版本问题?
ThirdPartyLibrary.BugFactory 可能是一种不同的类型,如果您有两个不同版本的第三方程序集以某种方式被引用:一个在编译时,另一个在您签名/验证时不同。
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..
听起来您只是通过“添加引用”对话框引用 COM 库。您可能应该为可以签名的 COM 库创建一个主互操作程序集。对程序集进行签名的注意事项之一是它引用的所有程序集也必须进行签名。
您通常会使用 SDK 程序 TlbImp:
TlbImp yourcomlibrary.tlb /primary /keyfile:yourkeyfile.snk /out:yourcomlibrary.dll
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
您的
IConnection
界面是什么样的?看起来您的ThirdPartyLibrary
有一个BugFactory
对象,并且您的项目或其他引用中也有一个BugFactory
对象。您是否尝试更改接口和具体类型以显式使用 ThirdPartyLibrary.BugFactory 作为该方法的返回类型?What does your
IConnection
interface look like? It seems like yourThirdPartyLibrary
has aBugFactory
object and you also have aBugFactory
object either in your project or another reference. Did you try changing both the interface and the concrete type to explicity useThirdPartyLibrary.BugFactory
as the return type for that method?