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

C# 在需要委托参数的多个重载泛型方法的类上的getmethod中使用的正确签名,c#,reflection,lambda,delegates,methodinfo,C#,Reflection,Lambda,Delegates,Methodinfo,在回答了部分问题后,这里有一些额外的信息,希望能够解决仍然存在的问题 开始编辑 var curEntityPI=ctx.GetType().GetProperties().Where(pr=>pr.Name==“Client”).First(); 类型curEntityType=curEntityPI.PropertyType.GetGenericArguments().First(); Type[]typeArgs={curEntityType}; 类型propertyManagerType=

在回答了部分问题后,这里有一些额外的信息,希望能够解决仍然存在的问题

开始编辑

var curEntityPI=ctx.GetType().GetProperties().Where(pr=>pr.Name==“Client”).First();
类型curEntityType=curEntityPI.PropertyType.GetGenericArguments().First();
Type[]typeArgs={curEntityType};
类型propertyManagerType=generic.MakeGenericType(typeArgs);
var propertyManager=Activator.CreateInstance(propertyManagerType,新对象[]{})

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

结束编辑

方法签名对反射来说应该是什么样子,我正在尝试调用与此等效的方法签名

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

反射和泛型在一起工作得很好,但是如何实现特定的目标是非常依赖于上下文的,因为可能有封闭的、开放的和部分封闭的类型和方法。尽管如此,使用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});
//从某处获取类型
var compileTimeUnknownType=Type.GetType(“三列”);
if(compileTimeUnknownType==null)
抛出新ArgumentException(“compileTimeUnknownType”);
var managerType=typeof(DynamicPropertyManager).MakeGenericType(compileTimeUnknownType);
var createPropertyMethod=managerType.GetMethods().Single(x=>
{
var p=x.GetParameters();
var g=x.GetGenericArguments();
返回x.Name==“CreateProperty”&&
p、 长度==3&&
g、 长度==2&&
p[0]。ParameterType==typeof(字符串)&&
p[1]。ParameterType==typeof(Func)。MakeGenericType(g)&&
p[2].ParameterType==typeof(属性[]);
});
var closedMethod=createPropertyMethod.MakeGenericMethod(新[]{compileTimeUnknownType,typeof(string)});
var parametexpr=Expression.Parameter(compileTimeUnknownType,“arg”);
兰姆达变种=
表达式.Lambda(typeof(Func).MakeGenericType(new[]{compileTimeUnknownType,typeof(string)}),
Expression.Constant(“Four”),new List(){paramExpr}).Compile();
var ret=closedMethod.Invoke(null,新对象[]{“四”,lambda,null});

您好,非常感谢您的回复,我认为createPropertyMethod会很好地工作,但我遇到的问题是,我使用反射的原因是ThreeColumns类在运行时之前是未知的。在我的例子中,我附加一个属性的类实际上是另一个泛型类,我通过反射得到了这个泛型类,然后用类类型see edit实例化了propertymanager实例。我修改了代码,现在
ThreeColumns
类型不再被编译时引用。非常感谢您查看此内容。我会试一试,然后接受并投票支持你的答案。你真的是个救命恩人,真的!一如所料。我花了一下午的大部分时间独自完成它,我得到了第一个通用位&Expression.Constant的使用,但不是paramExpr位。在我要做的事情中,有一些基本的东西让我困惑不解。非常感谢。
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);
    }
}
// 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});