簡體   English   中英

C# 如何使用 Reflection.Emit 調用帶有謂詞的 LINQ 的第一個方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM