views:

576

answers:

3

I want to work around the fact that my WCF servicelayer can not handle a generic method like this:

public void SaveOrUpdateDomainObject<T>(T domainObject)
{     
    domainRoot.SaveDomainObject<T>(domainObject);
}

so I built this workaround method instead

public void SaveOrUpdateDomainObject(object domainObject, string typeName)
{     
    Type T = Type.GetType(typeName);
    var o = (typeof(T))domainObject;
    domainRoot.SaveDomainObject<typeof(T)>(o);
}

The problem is this does not compile somehow.

I think this is the result of me not fully understanding the difference between

  • Type T I believe this is an object of type "Type"

  • the result of typeof(T) I believe this results in a non-object type version of the type of T (I don't know how to say this exactly)

+6  A: 

You don't need typeName: you have to either pass around Type instances, or use object.GetType() to retrieve object run-time type.

In either case,

MethodInfo genericSaveMethod = domainRoot.GetType().GetMethod("SaveDomainObject");
MethodInfo closedSaveMethod = genericSaveMethod .MakeGenericMethod(domainObject.GetType());
closedSaveMethod.Invoke(domainRoot, new object[] { domainObject });
Anton Gogolev
A: 

Unfortunately, something like this is quite hard in C#. It's easy to get the correct Type instance from a string, just like you did, but you'll have to use reflection to get the right method.

Try something along the lines of

public void SaveOrUpdateDomainObject(object domainObject, string typeName)
{
    Type T = Type.GetType(typeName);
    MethodInfo genericMethod = domainRoot.GetType().GetMethod("SaveDomainObject");
    MethodInfo method = genericMethod.MakeGenericMethod(T);
    method.Invoke(domainRoot, new object[] { domainObject });
}
Ruben
Wrong! Stop giving incorrect answers if you dont even try to compile it...
leppie
Ruben
However, just for the curious, I've modified it to compile. It's still the same answer as Anton's though.
Ruben
A: 

I think I had a similar problem, however did this which is a bit messy:

if (businessObject is Made4Print.Country) ((Made4Print.Country)businessObject).Save(); else if (businessObject is Made4Print.User) ((Made4Print.User)businessObject).Save();

... Loads of others...

else if (businessObject is Made4Print.Timezone) ((Made4Print.Timezone)businessObject).Save();

Will be interested in a better solution.

Mark Redman