Martin
Martin

Reputation: 10563

How to use reflection to call method by name

Hi I am trying to use C# reflection to call a method that is passed a parameter and in return passes back a result. How can I do that? I've tried a couple of things but with no success. I'm used to PHP and Python where this can be done on a single line so this is very confusing to me.

In essence this is how the call would be made without reflection:

response = service.CreateAmbience(request);

request has these objects:

request.UserId = (long)Constants.defaultAmbience["UserId"];
request.Ambience.CountryId = (long[])Constants.defaultAmbience["CountryId"];
request.Ambience.Name.DefaultText = (string)Constants.defaultAmbience["NameDefaultText"];
request.Ambience.Name.LanguageText = GetCultureTextLanguageText((string)Constants.defaultAmbience["NameCulture"], (string)Constants.defaultAmbience["NameText"]);
request.Ambience.Description.DefaultText = (string)Constants.defaultAmbience["DescriptionText"];
request.Ambience.Description.LanguageText = GetCultureTextLanguageText((string)Constants.defaultAmbience["DescriptionCulture"], (string)Constants.defaultAmbience["DescriptionDefaultText"]);

This is my function to implement the reflection where serviceAction for the case above would be "CreateAmbience":

public static R ResponseHelper<T,R>(T request, String serviceAction)
{
    ICMSCoreContentService service = new ContentServiceRef.CMSCoreContentServiceClient();
    R response = default(R);
    response = ???
}

Upvotes: 27

Views: 63710

Answers (4)

dtb
dtb

Reputation: 217293

You can use Delegate.CreateDelegate to obtain a delegate to the method by name:

public static R ResponseHelper<T,R>(T request, string serviceAction)
{
    var service = new ContentServiceRef.CMSCoreContentServiceClient();

    var func = (Func<T,R>)Delegate.CreateDelegate(typeof(Func<T,R>),
                                                  service,
                                                  serviceAction);

    return func(request);
}

Upvotes: 3

Stephen Cleary
Stephen Cleary

Reputation: 456507

If you're on .NET 4, use dynamic:

dynamic dService = service;
var response = dService.CreateAmbience(request);

Upvotes: 4

Brian Scott
Brian Scott

Reputation: 9361

Here's a quick example of calling an object method by name using reflection:

Type thisType = <your object>.GetType();
MethodInfo theMethod = thisType.GetMethod(<The Method Name>); 
theMethod.Invoke(this, <an object [] of parameters or null>); 

Upvotes: 15

Jon Skeet
Jon Skeet

Reputation: 1500525

Something along the lines of:

MethodInfo method = service.GetType().GetMethod(serviceAction);
object result = method.Invoke(service, new object[] { request });
return (R) result;

You may well want to add checks at each level though, to make sure the method in question is actually valid, that it has the right parameter types, and that it's got the right return type. This should be enough to get you started though.

Upvotes: 54

Related Questions