I am trying to get my first generic method work. Here is what I want to do:
Based on diffent type of users, we need to use different DLL. The DLL is COM object wrapper, which expose a function that can be called. The original code looks like the following:
using System.Runtime.InteropServices;
using AsynchWrapper1;
using AsynchWrapper2;
using AsynchWrapper3;
....
namespace MyNameSpace
{
public class Unility
{
public static void CallAsynchWrapper(int
clientType, int clientId)
{
if (clientType ==0)
{
clsAsynchWrapper1
asynchWrapper = new clsAsynchWrapper1();
asynchWrapper.XYZ(clientId);
Marshal.ReleaseComObject(asynchWrapper);
asynchWrapper = null;
}
else if
(clientType ==1)
{
clsAsynchWrapper2
asynchWrapper = new clsAsynchWrapper2();
asynchWrapper.XYZ(clientId);
Marshal.ReleaseComObject(asynchWrapper);
asynchWrapper = null;
}
else
{
clsAsynchWrapper3
asynchWrapper = new clsAsynchWrapper3();
asynchWrapper.XYZ(clientId);
Marshal.ReleaseComObject(asynchWrapper);
asynchWrapper = null;
}
}
}
Where XYZ is the function that all 3 dlld expose.
I want to make a generic method by modifying the CallAsynchWrapper function doing the following:
public static void
CallAsynchWrapper(int clientType, int
clientId)
{
if (clientType ==0)
{
clsAsynchWrapper1
asynchWrapper = new clsAsynchWrapper1();
genericCallAsynchWrapper
}
else if
(clientType ==1)
{
clsAsynchWrapper2
asynchWrapper = new clsAsynchWrapper2();
genericCallAsynchWrapper
}
else
{
clsAsynchWrapper3
asynchWrapper = new clsAsynchWrapper3();
genericCallAsynchWrapper
}
}
and add a generic method:
static void genericCallAsynchWrapper
{
asynchWrapper.XYZ(clientId);
Marshal.ReleaseComObject(asynchWrapper);
asynchWrapper = default(T);
}
When I compile it, I got error message” T doesn’t have a definition of XYZ.”
My first question is: Is that possible to make a generic method for what I am trying to do?
If that’s possible, how can I make compiler knows that T does have XYZ?
Does anybody know the answer?Thanks in advance for any help!
AlanPosted Feb 1, 2008, 3:45 PM
IUnknown is a very basic interface which all COM objects implement. It contains just three methods: QueryInterface(),AddRef() and Release(). The first of these returns a reference to an interface which the COM object implements, given its ID, and the other two are concerned with 'reference counting' which control object lifetime.
However, when a .NET program interacts with a COM object, it's not the object itself which it accesses but what's called a Runtime Callable Wrapper (or RCW) which serves as a bridge between .NET and COM.
The RCW handles calls to IUnknown and other low level interfaces so you won't see it actually exposed to .NET code.
What I'd suggest you do is to examine the COM objects with the Visual Studio object browser to see which interfaces are exposed by the RCW and whether the XYZ() method in each object is a member of a common interface. If it is, then you can use the name of this interface in the constraint for the generic method. Otherwise, there's nothing you can do in this respect.
VickyPosted Feb 1, 2008, 12:13 PM
Thank you for your help!
AlanPosted Jan 31, 2008, 7:51 PM
All COM objects implement interfaces (notably IUnknown) whatever language they're written in.
However, if the XYZ() method doesn't belong to a common interface then, no, I can't think of a way to do what you want using a C# generic method.
VickyPosted Jan 31, 2008, 5:33 PM
well, all 3 COM objects are written in C. they don't have interface...
Does that mean no any other solution any more???
AlanPosted Jan 31, 2008, 3:51 PM
The only way I can think of to get that to work is if all 3 COM objects implement the same interface (let's say IFace) which contains the XYZ method. You could then use a constraint to force the compiler to accept it:
static void genericCallAsynchWrapper(T asynchWrapper, int clientId) where T : IFace
{
asynchWrapper.XYZ(clientId);
Marshal.ReleaseComObject(asynchWrapper);
asynchWrapper = default(T);
}
Otherwise I think you'll have to stay with a non-generic solution.