使用需要委托参数的多个重载泛型方法在类的getmethod中使用的正确签名

时间:2016-12-05 22:10:24

标签: c# reflection lambda delegates methodinfo

在回答完成部分问题的答案之后,还有一些额外的信息可以解决仍有争议的问题

开始修改

var curEntityPI = ctx.GetType().GetProperties().Where(pr => pr.Name == "Client").First(); Type curEntityType = curEntityPI.PropertyType.GetGenericArguments().First(); Type[] typeArgs = { curEntityType }; Type propertyManagerType = generic.MakeGenericType(typeArgs); var propertyManager = Activator.CreateInstance(propertyManagerType, new object[] {});

考虑到这一点,我不能以与第一个答案中显示的相同的方式使用closeMethod.Invoke,它是Func和return body,我不知道如何在调用时放置

结束修改

方法签名对于反射应该是什么样的,我试图调用相应的

DynamicPropertyManager<ThreeColumns>.CreateProperty<ThreeColumns, string>(
     "Four",
     t => "Four",
     null
  ));

在此课程中找到http://putridparrot.com/blog/dynamically-extending-an-objects-properties-using-typedescriptor/

  1. 但我正在尝试使用反射。我正在努力奋斗 最重要的是获得正确的方法超载。

  2. 我必须诚实,虽然我也不完全确定如何通过反射为lambda位提供正确的参数 任

  3. 我打算尝试这部分,但不知道func位是什么     在做MakeGenericMethod

    时看起来像
    Func<string> funcArg = () => { return "Four"; };
    

    object[] args = { fieldOrPropertyName , funcArg, null };

    包含上述链接中的课程内容以供参考。

    public class DynamicPropertyManager<TTarget> : IDisposable
    {
        private readonly DynamicTypeDescriptionProvider provider;
        private readonly TTarget target;
    
        public DynamicPropertyManager()
        {
            Type type = typeof(TTarget);
    
            provider = new DynamicTypeDescriptionProvider(type);
            TypeDescriptor.AddProvider(provider, type);
        }
    
        public DynamicPropertyManager(TTarget target)
        {
            this.target = target;
    
            provider = new DynamicTypeDescriptionProvider(typeof(TTarget));
            TypeDescriptor.AddProvider(provider, target);
        }
    
        public IList<PropertyDescriptor> Properties
        {
            get { return provider.Properties; }
        }
    
        public void Dispose()
        {
            if (ReferenceEquals(target, null))
            {
                TypeDescriptor.RemoveProvider(provider, typeof(TTarget));
            }
            else
            {
                TypeDescriptor.RemoveProvider(provider, target);
            }
        }
    
        public static DynamicPropertyDescriptor<TTargetType, TPropertyType>
           CreateProperty<TTargetType, TPropertyType>(
               string displayName,
               Func<TTargetType, TPropertyType> getter,
               Action<TTargetType, TPropertyType> setter,
               Attribute[] attributes)
        {
            return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
               displayName, getter, setter, attributes);
        }
    
        public static DynamicPropertyDescriptor<TTargetType, TPropertyType>
           CreateProperty1<TTargetType, TPropertyType>(
              string displayName,
              Func<TTargetType, TPropertyType> getHandler,
              Attribute[] attributes)
        {
            return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
               displayName, getHandler, (t, p) => { }, attributes);
        }
    
        public static DynamicPropertyDescriptor<TTargetType, TPropertyType>
           CreateProperty<TTargetType, TPropertyType>(
              string displayName,
              Func<TTargetType, TPropertyType> getHandler,
              Attribute[] attributes)
        {
            return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
               displayName, getHandler, (t, p) => { }, attributes);
        }
    }
    

1 个答案:

答案 0 :(得分:1)

反思和泛型在一起工作得非常好,但是如何处理特定目标是非常依赖于上下文的,因为可能是封闭的,开放的和部分封闭的类型和方法。尽管如此,使用Linq通常很容易得到你想要的东西。看看:

// get type from somewhere
var compileTimeUnknownType = Type.GetType("ThreeColumns");

if (compileTimeUnknownType == null)
    throw new ArgumentException("compileTimeUnknownType");

var managerType = typeof (DynamicPropertyManager<>).MakeGenericType(compileTimeUnknownType);

var createPropertyMethod = managerType.GetMethods().Single(x =>
{
    var p = x.GetParameters();
    var g = x.GetGenericArguments();
    return x.Name == "CreateProperty" &&
            p.Length == 3 &&
            g.Length == 2 &&
            p[0].ParameterType == typeof (string) &&
            p[1].ParameterType == typeof (Func<,>).MakeGenericType(g) &&
            p[2].ParameterType == typeof (Attribute[]);
});

var closedMethod = createPropertyMethod.MakeGenericMethod(new[] {compileTimeUnknownType, typeof (string)});

var paramExpr = Expression.Parameter(compileTimeUnknownType, "arg");
var lambda =
    Expression.Lambda(typeof (Func<,>).MakeGenericType(new[] {compileTimeUnknownType, typeof (string)}),
        Expression.Constant("Four"), new List<ParameterExpression>() {paramExpr}).Compile();

var ret = closedMethod.Invoke(null, new object[] {"Four", lambda, null});