[英]Call a method using a MethodInfo instance on the stack using Reflection.Emit
[英]C# How to call LINQ's First method with predicate using Reflection.Emit
我試圖將我的頭包裹在 Reflection.Emit 周圍,我正在玩弄它以了解它是如何工作的。
我試圖實現這個方法:
public static object GetTableKeyValue(object tableValue) => tableValue.GetType().GetProperties().First(property => property.GetCustomAttribute<KeyAttribute>() is not null).GetValue(tableValue);
這是我到目前為止所做的:
public static object GetTableKeyValueReflectionEmit(object val)
{
var getTableKeyValue = new DynamicMethod("GetTableKeyValueReflectionEmit", typeof(object), new Type[] { typeof(object) }, typeof(object).Module);
getTableKeyValue.DefineParameter(1, ParameterAttributes.In, "tableValue");
var il = getTableKeyValue.GetILGenerator(256);
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, typeof(object).GetMethod(nameof(object.GetType)), null);
il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetProperties), new Type[] { }), null);
Func<PropertyInfo, bool> predicate = property => (!property.GetCustomAttribute<KeyAttribute>().Equals(null));
// im stuck here
il.EmitCall(OpCodes.Call, typeof(Enumerable).GetMember(nameof(Enumerable.First)).OfType<MethodInfo>().First(method => method.GetParameters().Length == 1), new Type[] { typeof(Func<PropertyInfo, bool>) });
il.EmitCall(OpCodes.Call, typeof(PropertyInfo).GetMethod(nameof(PropertyInfo.GetValue), new Type[] { typeof(object) }), new Type[] { typeof(object) });
il.Emit(OpCodes.Ret);
var getTableKeyValueDelegate = (GetTableKeyValueDelegate)getTableKeyValue.CreateDelegate(typeof(GetTableKeyValueDelegate));
return getTableKeyValueDelegate(val);
}
我無法理解如何定義 Func<PropertyInfo, bool> 類型的謂詞並將其傳遞給 First 方法,而且我真的找不到關於 Reflection.Emit 的好信息,我想這樣做並不常見。
幫助將不勝感激。
這似乎對我有用:
public static object GetTableKeyValueReflectionEmit(object val) {
var getTableKeyValue = new DynamicMethod("GetTableKeyValueReflectionEmit", typeof(object), new Type[] { typeof(object) }, typeof(object).Module);
getTableKeyValue.DefineParameter(1, ParameterAttributes.In, "tableValue");
var il = getTableKeyValue.GetILGenerator(256);
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, typeof(object).GetMethod(nameof(object.GetType)), null);
il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetProperties), new Type[] { }), null);
Func<PropertyInfo, bool> predicate = property => (!property.GetCustomAttribute<KeyAttribute>().Equals(null));
il.Emit(OpCodes.Ldftn, predicate.GetMethodInfo());
var miFirstGeneric = typeof(Enumerable).GetMember(nameof(Enumerable.First)).OfType<MethodInfo>().First(method => method.GetParameters().Length == 1);
var miFirst = miFirstGeneric.MakeGenericMethod(typeof(PropertyInfo));
il.Emit(OpCodes.Call, miFirst);
il.Emit(OpCodes.Call, typeof(PropertyInfo).GetMethod(nameof(PropertyInfo.GetValue), new Type[] { typeof(object) }));
il.Emit(OpCodes.Ret);
var getTableKeyValueDelegate = (GetTableKeyValueDelegate)getTableKeyValue.CreateDelegate(typeof(GetTableKeyValueDelegate));
return getTableKeyValueDelegate(val);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.