views:

69

answers:

2

I am consuming a web service which has a number of methods (50) which create different objects.
example:
CreateObject1(Object1 obj, int arg2)
CreateObject2(Object2 obj, int arg2)
...
CreateObjectX(ObjectX obj, int arg2)

All Objects (Object1, Object2, ObjectX...) inherit from ObjectBase.

So I am trying to do this...

delegate void DlgtCreateObject(ObjectBase obj, int arg2);

public void CreateObject(ObjectBase obj, int arg2) 
{
    DlgtCreateObject dlgt;
    string objType;
    string operation;

    objType = obj.GetType().ToString();
    operation = "Create" + objType.Substring(objType.LastIndexOf(".") + 1);

    using (MyWebService service = new MyWebService())
    {

        dlgt = (DlgtCreateObject)Delegate.CreateDelegate(typeof(DlgtCreateObject),
                                                         service,
                                                         operation,
                                                         false,
                                                         true);
        dlgt(obj, arg2);
    }
}   

Unfortunately this gives me a Failed to Bind exception. I believe this is because my delegate signature uses the ObjectBase as its first argument where the functions use the specific classes.

Is there a way around this?

+1  A: 

If you're only trying to call the methods within here, I suggest you use Type.GetMethod and MethodBase.Invoke instead of going via delegates. Then you won't run into this problem.

Jon Skeet
It seems I was able to solve my dilemma with a generic delegate. What are the benefits of using GetMethod and Invoke over delegates?
Nate Heinrich
I assume it would look like this... service.GetType().GetMethod(operation).Invoke(service, new object[] {obj, arg2});
Nate Heinrich
@Nate: Basically you don't need to have the right delegate type if you're just trying to invoke the method. Going via CreateDelegate seems a little longwinded.
Jon Skeet
Sounds good, going with your suggestion. Thanks!
Nate Heinrich
A: 

Right after posting I figured generics might be the answer, and indeed the following seems to do the trick...

delegate void DlgtCreateObject<T>(T obj, int arg2) where T : ObjectBase;

public void CreateObject<T>(T obj, int arg2) where T : ObjectBase; 
{
    DlgtCreateObject dlgt;
    string objType;
    string operation;

    objType = obj.GetType().ToString();
    operation = "Create" + objType.Substring(objType.LastIndexOf(".") + 1);

    using (MyWebService service = new MyWebService())
    {

        dlgt = (DlgtCreateObject<T>)Delegate.CreateDelegate(typeof(DlgtCreateObject<T>),
                                                 service,
                                                 operation,
                                                 false,
                                                 true);
        dlgt(obj, arg2);
    }
}      
Nate Heinrich