签署 C# 程序集时出现接口未实现错误

发布于 2024-08-17 13:18:35 字数 1378 浏览 2 评论 0原文

我一直在尝试签署程序集并收到此错误:

“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风挽心 2024-08-24 13:18:35

我仍然怀疑 new 关键字是否会导致此错误。

你说“我不认为 new 关键字是问题,因为 1) 删除它并不能阻止错误”,但你必须记住,如果你的方法隐藏了基本方法,编译器将添加一个 new,即使您没有指定它,除非您明确指定override

所有显式的 new 所做的都是为了防止编译器警告(而不是错误)。

真的有隐藏或覆盖的方法吗?

如果您在此方法上指定 virtual 而不是 new,会发生什么情况。它能编译吗?是否会出现“找不到合适的方法来覆盖”的错误?

[编辑以回应您的评论]

我收到此错误:
“'Utils.Connection.BugFactory()':
无法覆盖,因为
'ThirdPartyLibrary.ConnectionClass.BugFactory'
不是一个函数。”原文
ThirdPartyLibrary.ConnectionClass.BugFactory
是一个属性。

我怀疑这可能是问题所在。您正在使用方法覆盖属性。

通过使用 new 关键字,您可以向任何引用您的派生类的人隐藏旧属性。

相比之下,任何将引用强制转换为超类(您继承的超类)的人都会看到旧属性,而不是您的新方法。

您能否提供更多超类(或接口)以及派生类的代码?

[编辑以回应您的评论]

我正在尝试将界面更改为
让 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"?

抽个烟儿 2024-08-24 13:18:35

命名空间/版本问题?

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..

清泪尽 2024-08-24 13:18:35

听起来您只是通过“添加引用”对话框引用 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

悍妇囚夫 2024-08-24 13:18:35

您的 IConnection 界面是什么样的?看起来您的 ThirdPartyLibrary 有一个 BugFactory 对象,并且您的项目或其他引用中也有一个 BugFactory 对象。您是否尝试更改接口和具体类型以显式使用 ThirdPartyLibrary.BugFactory 作为该方法的返回类型?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文