C# ComVisible class not working when derives from Generic class?

1,061 views
Skip to first unread message

Terry Aney

unread,
Dec 28, 2015, 11:49:58 AM12/28/15
to Excel-DNA
Hi, when I had the following in C# ExcelDNA class, everything worked well...

[ComVisible( true )]
[ClassInterface( ClassInterfaceType.AutoDispatch )]
[ProgId( "BTR.Extensibility.Excel.VBAHelpers" )]
public class VBAHelpers
{
// methods here...
}



And from Spreadsheet VBA code, i could do something like this..

Dim btr As Object: Set btr = CreateObject("BTR.Extensibility.Excel.VBAHelpers")

However, I did some refactoring because VBAHelpers needed to share some code with another 'excel' library so I changed it to...
[ComVisible( true )]
[ClassInterface( ClassInterfaceType.AutoDispatch )]
[ProgId( "BTR.Extensibility.Excel.VBAHelpers" )]
public class VBAHelpers : MacroProcessor<ExcelReference>
{
 
// methods here...
}

But now in VBA when I try to create the object, I get the following (non-helpful) error...


I then also tried to do something like:


[ComVisible( true )]
[ClassInterface( ClassInterfaceType.AutoDispatch )]
[ProgId( "BTR.Extensibility.Excel.VBAHelpers" )]
public class VBAHelpers : VBAHelpersGeneric }

public class VBAHelpersGeneric : MacroProcessor<ExcelReference>
{
 
// methods here...
}



But that didn't work either.  Is there any way to make my class visible to Com but use the generic implementation?



Govert van Drimmelen

unread,
Dec 28, 2015, 2:32:24 PM12/28/15
to exce...@googlegroups.com
Hi Terry,

When I try this in Visual Studio, I get quite a nice Warning message:

Type library exporter warning processing 'TestComRegistration.MyClass, TestComRegistration'.
Warning: Type library exporter encountered a type that derives from a generic class and is not marked as [ClassInterface(ClassInterfaceType.None)]. Class interfaces cannot be exposed for such types. Consider marking the type with [ClassInterface(ClassInterfaceType.None)] and exposing an explicit interface as the default interface to COM using the ComDefaultInterface attribute.

Basically the problem with having the generic base class is that the class interface cannot be generated automatically for generic types. By changing the attribute to [ClassInterface(ClassInterfaceType.None)] you stop the compiler from trying to generate the automatic class interface. To still expose your code, you then need a (non-generic) interface definition and you set this interface as the default COM interface for your class. You might also need to mark this interface as InterfaceType(ComInterfaceType.InterfaceIsDual) for the late-binding to work from VBA.

So you might experiment with code like this:

using System;
using System.Runtime.InteropServices;

namespace TestComRegistration
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IMyMethods
    {
        string GetName();
    }

    public class MyBase<T> where T : class
    {
        public string BaseName()
        {
            return "MyBase";
        }
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IMyMethods))]
    public class MyClass : MyBase<string>, IMyMethods
    {
        public string GetName()
        {
            throw new NotImplementedException();
        }

        public string MyName()
        {
            return "MyClass";
        }
    }
}

(It compiles without warning, but I haven't tried this from VBA...)

Cheers,
Govert


From: exce...@googlegroups.com [exce...@googlegroups.com] on behalf of Terry Aney [terry...@gmail.com]
Sent: 28 December 2015 06:49 PM
To: Excel-DNA
Subject: [ExcelDna] C# ComVisible class not working when derives from Generic class?

--
You received this message because you are subscribed to the Google Groups "Excel-DNA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to exceldna+u...@googlegroups.com.
To post to this group, send email to exce...@googlegroups.com.
Visit this group at https://groups.google.com/group/exceldna.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages