更新时间:2023-09-13 15:15:16
首先不要使用反射,除非你需要它并且你知道你在做什么,所以如果你的方法计数很低使用switch语句:
switch (comm.Method)
{
case method1 : this .Method1(comm.Data); break ;
... // 依此类推
}
您还可以使用预先填充的方法处理程序委托使用 字典<字符串,操作>
。
如果你真的需要使用反射,那么你应该首先找出代码的位置很慢,然后使用 Dictionary $开始缓存
Delegate.CreateDelegate
c $ c>更快查询:
加速反射调用C#/ .NET - 堆栈溢出 [ ^ ] 扩展Mehdi Gholam的解决方案,以下是方法
ProcessFileType
发现需要转换的数据类型,查找数据类型,然后执行转换来自JSON字符串并返回特定类型的类结构。
// 只有一些类型是简要列表
private readonly 字典<字符串,Func< JObject,文件>> mimeTypes
= new Dictionary< string,Func< JObject,File>>
{
{ application / vnd.google-apps.folder,转换< Folder>()},
{ image / jpeg,转换< JpgImage> ;()},
{ image / png,转换< PngImage>() },
{ application / zip,转换< Zipped>()},
{ application / x-zip-compressed,转换< Zipped>()},
{ video / mp4,转换< Mp4Video>()},
{ text / plain,转换< TxtDocument>()},
{ application / vnd.openxmlformats-officedoc ument.presentationml.presentation,
转换< PptDocument>()},
{ application / vnd.openxmlformats-officedocument.wordprocessingml.document,
转换< WordDocument>()}
};
// 转换类型的文件.... 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。添加(MIMETYPES [键](jObjs [I]));
}
}
}
// 转换Json将对象数据转换为指定的类类型
private static Func< JObject,文件>转换< TModel>()其中 TModel:文件
{
return (jObj )= > JsonHelper.ToClass< TModel>(jObj.ToString());
}
要使用Reflection执行完全相同的操作,它看起来像这样:
public JsonDataTypeConverter()
{
if (convert == null )
convert = GetType()。GetMethod( nameof (转换),
BindingFlags.Instance | BindingFlags.NonPublic);
}
private static MethodInfo convert; // 在类实例化时配置
// 只有一些类型是简要列表
private static readonly 字典<字符串,类型> mimeTypes = new 字典<字符串,类型>
{
{ application / vnd.google-apps.folder, typeof (文件夹)},
{ image / jpeg, typeof (JpgImage)},
{ image / png, typeof (PngImage)},
{ application / zip, typeof (Zipped)},
{ application / x-zip-compressed, typeof (Zipped)},
{ video / mp4, typeof (Mp4Video)},
{ text /纯, typeof (TxtDocument)},
{ application / vnd.openxmlformats-officedocument.presentationml.presentation,
typeof (PptDocument)},
{ application / vnd.openxmlformats-officedocument.wordprocessingml.document,
typeof (WordDocument)}
};
// 转换类型的文件.... 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);
}
}
}
// 转换Json将对象数据转换为指定的类类型
private TModel转换< TModel>(JObject jObj)其中 TModel:IResourceKind
{
return JsonHelper.ToClass< TModel>(jObj.ToString());
}
如果您想查看代码的实际应用,可以从本文下载:在C#中使用JSON& VB [ ^ ](Google云端硬盘 - 文件资源管理器示例)
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:
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);
}
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: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 theDelegate.CreateDelegate
using aDictionary
for faster lookup:
Speeding up Reflection Invoke C#/.NET - Stack Overflow[^]
Expanding on Mehdi Gholam's solution, here is a real-life example of where the methodProcessFileType
"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.// 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: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)