Click here to Skip to main content
15,884,388 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
I am using the Invoke method to call method using reflection. Performance of this not great. Is there any other solution

What I have tried:

C#
void ExecuteMethodViaReflection(TestObj comm)
{
    var paramNames = comm.paramNames; //of type string array
    var paramData = comm.Data; //of type Object array

    Type t = this.GetType();
    t.InvokeMember(comm.Method, BindingFlags.InvokeMethod, null, this, paramData, null, null, paramNames);
    }
Posted
Updated 19-Aug-17 0:04am
v2
Comments
Dave Kreskowiak 18-Aug-17 16:01pm    
Yeah, don't use Reflection. It's notoriously slow.

You're going to have to describe why you think you need to use it in the first place.
[no name] 18-Aug-17 18:11pm    
haha a 5!
MYQueries1 18-Aug-17 16:10pm    
How i can rewrite the code to have better performance. Can i have small code snippet?
PIEBALDconsult 18-Aug-17 16:15pm    
Use Reflection to get the MethodInfo ONCE! then cache it and use it many times.
MYQueries1 18-Aug-17 16:19pm    
How i can invoke method with the parameters ? if there are overload methods? Can u post small code snippet . It will be very helpful

First don't use reflection unless you need it and you know what you are doing, so if your method counts is low use a switch statement:
C#
switch(comm.Method)
{
    case "method1" : this.Method1(comm.Data); break;
    ...// and so on
}
You can also use a Dictionary<string, Action> with pre-populated method handler delegates.

If you really need to use reflection then you should first find out where you code is slow then start caching the Delegate.CreateDelegate using a Dictionary for faster lookup:

Speeding up Reflection Invoke C#/.NET - Stack Overflow[^]
 
Share this answer
 
Comments
MYQueries1 19-Aug-17 4:48am    
I can't use the switch case here i have overload functions. It may break at that time
Graeme_Grant 19-Aug-17 5:58am    
Without knowing specifics, like sample code of the methods that you want to invoke and in what context, it is hard to give better solutions. However, I do have a solution that I can post once I know more specifics.,. Please click on the "Improve question" widget and supply specifics. So remove the body from the sample functions as we don't need to know what they do, just the method signatures and how they are being called.

Update: Check out solution #2... It is a real-life comparison of how to do it with and without reflection...
Expanding on Mehdi Gholam's solution, here is a real-life example of where the method ProcessFileType "discovers" the type of data that it needs to convert to, looks up the type of data, then executes the conversion from JSON string and returns a class structure of a specific type.
C#
// only some types are lists for briefity
private readonly Dictionary<string, Func<JObject, File>> mimeTypes
    = new Dictionary<string, Func<JObject, File>>
{
    { "application/vnd.google-apps.folder", Convert<Folder>() },
    { "image/jpeg", Convert<JpgImage>() },
    { "image/png", Convert<PngImage>() },
    { "application/zip", Convert<Zipped>() },
    { "application/x-zip-compressed", Convert<Zipped>() },
    { "video/mp4", Convert<Mp4Video>() },
    { "text/plain", Convert<TxtDocument>() },
    { "application/vnd.openxmlformats-officedocument.presentationml.presentation",
      Convert<PptDocument>() },
    { "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      Convert<WordDocument>() }
};

// Convert file of type.... mimeTypes
private void ProcessFileType(List<File> results, IList<JObject> jObjs, int i)
{
    var fileToken = jObjs[i].FindTokens("mimeType");
    if (fileToken != null && fileToken.Count > 0)
    {
        var key = mimeTypes.Keys.FirstOrDefault(x => x.Equals(fileToken[0].ToString()));
        if (key != null)
        {
            results.Add(mimeTypes[key](jObjs[i]));
        }
    }
}

// Convert Json Object data into a specified class type
private static Func<JObject, File> Convert<TModel>() where TModel : File
{
    return (jObj) => JsonHelper.ToClass<TModel>(jObj.ToString());
}

To do exactly the same thing slower using Reflection, it would look something like this:
C#
public JsonDataTypeConverter()
{
    if (convert == null)
        convert = GetType().GetMethod(nameof(Convert),
                                      BindingFlags.Instance | BindingFlags.NonPublic);
}

private static MethodInfo convert; // configured on class instantiation

// only some types are lists for briefity
private static readonly Dictionary<string, Type> mimeTypes = new Dictionary<string, Type>
{
    { "application/vnd.google-apps.folder", typeof(Folder) },
    { "image/jpeg", typeof(JpgImage) },
    { "image/png", typeof(PngImage) },
    { "application/zip", typeof(Zipped) },
    { "application/x-zip-compressed", typeof(Zipped) },
    { "video/mp4", typeof(Mp4Video) },
    { "text/plain", typeof(TxtDocument) },
    { "application/vnd.openxmlformats-officedocument.presentationml.presentation",
      typeof(PptDocument) },
    { "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      typeof(WordDocument) }
};

// Convert file of type.... mimeTypes
private void ProcessFileType(List<File> results, IList<JObject> jObjs, int i)
{
    var fileToken = jObjs[i].FindTokens("mimeType");
    if (fileToken != null && fileToken.Count > 0)
    {
        var key = mimeTypes.Keys.FirstOrDefault(x => x.Equals(fileToken[0].ToString()));
        if (key != null)
        {
            var method = convert.MakeGenericMethod(new[] { mimeTypes[key] });
            var data = method.Invoke(this, new[] { jObjs[i] });
            results.Add((File)data);
        }
    }
}

// Convert Json Object data into a specified class type
private TModel Convert<TModel>(JObject jObj) where TModel : IResourceKind
{
    return JsonHelper.ToClass<TModel>(jObj.ToString());
}

If you want to see the code in action, you can download it from this article: Working with JSON in C# & VB[^] (Google Drive - File Explorer example)
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900