简体   繁体   English

C# 如何使用 Reflection.Emit 调用带有谓词的 LINQ 的第一个方法

[英]C# How to call LINQ's First method with predicate using Reflection.Emit

im trying to wrap my head around Reflection.Emit, im playing around with it to understand how it works.我试图将我的头包裹在 Reflection.Emit 周围,我正在玩弄它以了解它是如何工作的。

im trying to implement this method:我试图实现这个方法:

public static object GetTableKeyValue(object tableValue) => tableValue.GetType().GetProperties().First(property => property.GetCustomAttribute<KeyAttribute>() is not null).GetValue(tableValue);

This is what i did so far:这是我到目前为止所做的:

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);
        }

i cant understand how to define a predicate of type Func<PropertyInfo, bool> and pass it to the First method, and i cant really find good information on Reflection.Emit, i guess its not that common to do it.我无法理解如何定义 Func<PropertyInfo, bool> 类型的谓词并将其传递给 First 方法,而且我真的找不到关于 Reflection.Emit 的好信息,我想这样做并不常见。

Help would be appreciated.帮助将不胜感激。

This seems to be working for me:这似乎对我有用:

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