'Method 'set_Description' in type 'myAssembly.NetProduct' from assembly 'myAssembly' does not have an implementation

I have a DLL file created in VB6. It contains a class named Product and that contains the following simple code:

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

I want to use this DLL in VB.NET, which is nothing more than registering the DLL on my system and including the DLL file in the references. Visual Studio automatically generates an interop DLL to consume the COM DLL. This interop DLL generates interfaces for all classes. In VB.NET I want to create a new class that implements the Product interface from the interop DLL. So I code:

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

The property is auto-generated because I implemented the Product interface. But here comes the problem because when I start using the NetProduct class I get an error telling me this:

Method 'set_Description' in type 'myProject.NetProduct' from assembly 'myProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

The problem is that there is no method set_Description in the interface. When I view the definition of the Product interface it shows me the following:

Imports System.Runtime.InteropServices

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

The definition of the _Product interface is:

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

When I use the interface myAssembly.Product directly to create a new object then everything works as you would expect. The property does not pose a problem there. But when I implement the interface in a .NET class the problem arises.

How do I solve this?

[update 1] After creating a method Set_Description I see the following error appear:

property 'Description' implicitly defines 'set_Description', which conflicts with a member of the same name in class 'NetProduct'.

This must have something to do with my problem, although I don't know what it is. I already tried completing the property to make sure the Throw New NotImplementedException() wouldn't be in the way but that didn't make the error go away. My code builds just fine by the way. The error I gave earlier is a runtime error. Not a build error.

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

[update 2] I have used JetBrains DotPeek to disassemble the interop.dll that Visual Studio generates. Disassembly is coded in C#. It contains 2 interfaces and 1 class for the single Product class from VB6. Here are all details.

I'll start with the Product class itself.

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; }
  }
}

The ProductClass uses 2 interfaces. I don't understand why because one of those is just an implementation of the other. This is the Product interface.

using System.Runtime.InteropServices;

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

And then we have the _Product interface. They even share the same Guid. It might have something to do with backwards compatibility.

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; }
  }
}

This is all I could find. Still no clue where the error for Set_Description comes from.

[Update 3] Example code

The code for the VB6 class is on top of this question. Nothing fancy there. The code for testing implementation in .NET is like this:

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

To test the NetProduct class I dropped a Button on a Form and create an instance of the class when the button is being clicked.

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

The whole project compiles without errors. The project even runs without errors UNTIL you click the button. Probably because the NetProduct type is first loaded on that point.



Solution 1:[1]

I used a console app to do my test. Other than that, my VB.NET code is basically identical to yours in update 3. The VB.NET properties were auto-generated by VS with the stub Throw New NotImplementedException() after using the Implements statement :

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

Same is true for the VB6 code. The string property is implemented like yours. Distinguishing factors so far:

  • VS 2019 vs. VS 2017
  • (Consuming) GUI vs. Console application
  • Different property names

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hel O'Ween