程序集'myAssembly'的类型 'myAssembly.NetProduct' 中的方法'set_Description'没有实现



我在VB6中创建了一个DLL文件。它包含一个名为Product的类,其中包含以下简单代码:

Option Explicit
Private sDescription As String
Public Property Get Description() As String
Description = sDescription
End Property
Public Property Let Description(Value As String)
sDescription = Value
End Property

我想在VB.NET中使用这个DLL,这只不过是在我的系统上注册DLL,并在引用中包含DLL文件。Visual Studio自动生成一个互操作DLL以使用COM DLL。此互操作DLL为所有类生成接口。在VB.NET中,我想创建一个新类,从互操作DLL实现Product接口。所以我编码:

Imports myAssembly
Public Class NetProduct
Implements myAssembly.Product
Public Property Description As String Implements _Product.Description
Get
Throw New NotImplementedException()
End Get
Set(value As String)
Throw New NotImplementedException()
End Set
End Property
End Class

该属性是自动生成的,因为我实现了Product接口。但问题来了,因为当我开始使用NetProduct类时,我会收到一个错误,告诉我:

来自的类型"myProject.NetProduct"中的方法"set_Description"程序集'myProject,版本=1.0.0.0,区域性=中性,PublicKeyToken=null"没有实现。"。

问题是接口中没有方法set_Description。当我查看Product接口的定义时,它会显示以下内容:

Imports System.Runtime.InteropServices
Namespace myAssembly
<CoClass(GetType(ProductClass))> <Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")>
Public Interface Product
Implements _Product
End Interface
End Namespace

_Product接口的定义是:

Imports System.Runtime.InteropServices
Namespace myAssembly
<Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")> <TypeLibTypeAttribute(4304)>
Public Interface _Product <DispId(1745027072)>
Property Description As String
End Interface
End Namespace

当我直接使用接口myAssembly.Product创建一个新对象时,一切都如您所期望的那样工作。该房产不会在那里造成问题。但是当我在.NET类中实现接口时,问题就出现了。

我该如何解决此问题?

[更新1]创建方法Set_Description后,我看到出现以下错误:

属性"Description"隐式定义了"set_Description"与类"NetProduct"中的同名成员冲突。

这一定与我的问题有关,尽管我不知道它是什么。我已经尝试完成属性以确保Throw New NotImplementedException()不会妨碍,但这并没有使错误消失。顺便说一下,我的代码构建得很好。我前面给出的错误是运行时错误。不是生成错误。

Private myDescription As String
Public Property Description As String Implements Product.Description
Get
Return myDescription
End Get
Set(value As String)
myDescription = value
End Set
End Property

[更新2]我已经使用JetBrains DotPeek来反汇编Visual Studio生成的interop.dll。反汇编以C#进行编码。它包含2个接口和1个类,用于VB6中的单个Product类。以下是所有细节。

我将从Product类本身开始。

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace myAssembly
{
[ClassInterface(0)]
[Guid("C54B96A8-1499-4B76-8508-0B732E551326")]
[TypeLibType(2)]
[ComImport]
public class ProductClass : _Product, Product
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern ProductClass();
[DispId(1745027072)]
public virtual extern string Description { [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.BStr)] get; [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [param: MarshalAs(UnmanagedType.BStr), In, Out] set; }
}
}

ProductClass使用2个接口。我不明白为什么,因为其中一个只是另一个的实现。这是Product接口。

using System.Runtime.InteropServices;
namespace myAssembly
{
[CoClass(typeof (ProductClass))]
[Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")]
[ComImport]
public interface Product : _Product
{
}
}

然后我们有了_Product接口。他们甚至共享相同的Guid。这可能与向后兼容性有关。

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace myAssembly
{
[Guid("49CE2F98-931C-441B-B322-9F39B6D6F212")]
[TypeLibType(4304)]
[ComImport]
public interface _Product
{
[DispId(1745027072)]
string Description { [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [return: MarshalAs(UnmanagedType.BStr)] get; [DispId(1745027072), MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] [param: MarshalAs(UnmanagedType.BStr), In, Out] set; }
}
}

这就是我能找到的全部。仍然不知道Set_Description的错误来自哪里。

[更新3]示例代码

VB6类的代码位于这个问题的顶部。那里没有什么新奇的东西。在.NET中测试实现的代码如下:

Imports myAssembly
Public Class NetProduct
Implements myAssembly.Product
Private myDescription As String
Public Property Description As String Implements Product.Description
Get
Return myDescription
End Get
Set(value As String)
myDescription = value
End Set
End Property
End Class

为了测试NetProduct类,我在Form上放置了一个Button,并在单击按钮时创建该类的实例。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '<- Error happens here, so on loading the datatype!
Dim Product As New NetProduct 'Error does NOT happen here.
End Sub

整个项目编译无误。项目运行时甚至没有错误,直到您单击按钮为止。可能是因为NetProduct类型首先加载在该点上。

我使用了一个控制台应用程序来进行测试。除此之外,我的VB.NET代码与更新3中的代码基本相同。VB.NET属性是VS在使用Implements语句后使用存根Throw New NotImplementedException()自动生成的:

Imports OurCOMDll
Class TestClass
Implements OurCOMDll.ClassInCOMDll
Dim msStringProperty As String = String.Empty
Public Property StringProperty As String Implements _ClassInCOMDll.StringProperty
Get
StringProperty= msStringProperty
End Get
Set(value As String)
msStringProperty = value
End Set
End Property
End Class
Module Module1
Sub Main()
Dim o As New OurCOMDll.ClassInCOMDll
o.StringProperty = "Hello World!"
Console.WriteLine(o.StringProperty) ' Outputs 'Hello World!' as expected
Console.ReadLine()
End Sub
End Module

VB6代码也是如此。字符串属性的实现方式与您的类似。迄今为止的区别因素:

  • 2019年VS 2017年
  • (消费(GUI与控制台应用程序
  • 不同的属性名称

最新更新