Groups | Blog | Home
all groups > dotnet interop > july 2006 >

dotnet interop : How to expose generic classes to COM?


Patricio
7/11/2006 10:56:34 AM
Hello,

We have a set of C# classes with their interfaces exposed to COM:

MatrixUInt16 : IMatrixUInt16
MatrixUInt32 : IMatrixUInt32
MatrixInt16 : IMatrixInt16
MatrixInt32 : IMatrixInt32

We are moving to VS2005 and these C# classes are excellent candidates for a
generic implementation, Matrix<T> : IMatrix<T>. Actually, the move to VS2005
is mainly because we have several of these type of class sets.

The question now is: How do we make these generic classes visible to COM?
I read that a generic type can not be exposed to COM, and that we should
create COM frienly wrappers like:

MatrixUInt16 : Matrix<UInt16>, IMatrixUInt16

where IMatrixUInt16 is COM visible. The problem with this approach is that
the server exposes collections of objects that will be of type IMatrix<T>
that will not be visible to the COM client.

Ideally I would like to have each specific IMatrix<T> to have a different
COM GUID.

Thank you in advance for your answers,
Patricio.


v-phuang NO[at]SPAM online.microsoft.com (
7/12/2006 12:00:00 AM
Hi Patricio,

Based on my testing, it is hard to do that.
Because IDL did not support Generic, it is hard to know how many class we
should generate for the generics class.
e.g.
For the interface IMatrix<T>, we did not know how many class should be
expose to COM and generate in the TLB file, because the generics is done in
the compile time.
IMatrix<int>,IMatrix<UInt>,IMatrix<Some cusomtized data type>..........

For your scenario, I think you may have to write four interface(no generics
and implement them in the same class)
But the same implement detailed can be in the same class, and the four
interface implement can be delegated to the class implement detailed.
Here is some code snippet for your reference only.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace GenericsClassCOM
{
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IMatrixInt
{
int Test(int i);
}
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IMatrixString
{
string Test(string s);
}
[ClassInterface(ClassInterfaceType.None)]
public class MyMatrix : IMatrixInt,IMatrixString
{
#region IMatrixInt Members

public int Test(int i)
{
return (new MatrixClass<int>()).Test(i);
}

#endregion

#region IMatrixString Members

public string Test(string s)
{
return (new MatrixClass<string>()).Test(s);
}

#endregion
}

internal class MatrixClass<T>
{
public T Test(T t)
{
//Concrete implement.
//
//
return t;
}
}
}



Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Patricio
7/12/2006 12:32:55 PM
Thank you Peter for your answer. Yes, it seems that we will need to go that
route.

To avoid delegating all the methods we are planning to do something like:

public class MyMatrixInt : MyMatrix<int>, IMatrixInt
{
}

public class MyMatrixString : MyMatrix<string>, IMatrixString
{
}

Best regards,
Patricio.

[quoted text, click to view]

v-phuang NO[at]SPAM online.microsoft.com (
7/13/2006 12:00:00 AM
Hi Patricio,

Thanks for your reply.
My code is just for demo. I think may have your own implement per your
concrete scenario.
If you still have any concern, please feel free to post here.



Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
AddThis Social Bookmark Button