[英]Use reflection to invoke method
在使用Azure ServiceFabric時,我們使用StateManager.GetStateAsync
方法來獲取值,該方法可用於在類之類的對象類型中獲取值。
我正在嘗試下面的代碼
var typeObj = Activator.CreateInstance(type);
var method = typeof(IActorStateManager).GetMethod(nameof(IActorStateManager.GetStateAsync));
var generic = method.MakeGenericMethod(type);
dynamic task = generic.Invoke(typeObj, new[] { stateName })
object result = await task;
通過這種方法,我得到了例外。
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146232829
HelpLink: null
InnerException: null
Message: "Object does not match target type."
Source: "mscorlib"
StackTrace: "at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)"
TargetSite: {Void CheckConsistency(System.Object)}
最有可能的是,這里有些事情被弄糊塗了。 如果您的代碼就是您實際執行的代碼,則說明您過度/濫用了type
變量。
讓我們確定該type
為具體的ActorStateManager
。 然后
var typeObj = Activator.CreateInstance(type); // typeobj is now ActorStateManager
錯誤可能在這里:
var generic = method.MakeGenericMethod(type);
// generic is now StateManager.GetStateAsync<ActorStateManager>
您的意圖不是創建StateManager.GetStateAsync<ActorStateManager>
,而是創建StateManager.GetStateAsync<ActorStateManager>
StateManager.GetStateAsync<bool>
或StateManager.GetStateAsync<DateTime>
。
另外,我的GetStateAsync 將(可選)cancellationToken作為第二個參數,最好在進行反射時明確顯示。
所以我想這就是您想要做的:
public async Task<object> TryLotsOfTypesAndIgnoreErrors(string stateName)
{
var typeObj = Activator.CreateInstance(typeof(ActorStateManager));
foreach (var typeParam in new[] {typeof(bool), typeof(string)})
{
try
{
var method = typeof(IActorStateManager).GetMethod(nameof(IActorStateManager.GetStateAsync));
var generic = method.MakeGenericMethod(typeParam);
var task = (Task) generic.Invoke(typeObj, new object[] { stateName, CancellationToken.None });
await task;
return task.GetType().GetProperty(nameof(Task<object>.Result))?.GetValue(task);
}
catch
{
// TODO: Catch only exception specific to type mismatch
}
}
return null;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.