mardi 1 décembre 2020

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.

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.

Help would be appreciated.





Aucun commentaire:

Enregistrer un commentaire