C# 在C中作为参数传递未知参数/返回类型的方法#

C# 在C中作为参数传递未知参数/返回类型的方法#,c#,reflection,linq-expressions,methodinfo,C#,Reflection,Linq Expressions,Methodinfo,这里有一个类似的问题: 假设您知道方法的参数和返回类型。我想做点不一样的事。我希望创建System.Reflection的.GetMethod(string)的一个版本,该版本采用lambda函数,因此: MethodInfo methodInfo = typeof(MyClass).GetMethod("AddThing"); 我可以使用更安全的编译: MethodInfo methodInfo = ReflectionHelper.GetMethod<MyClass>(mc

这里有一个类似的问题:

假设您知道方法的参数和返回类型。我想做点不一样的事。我希望创建System.Reflection的.GetMethod(string)的一个版本,该版本采用lambda函数,因此:

MethodInfo methodInfo = typeof(MyClass).GetMethod("AddThing");
我可以使用更安全的编译:

MethodInfo methodInfo = ReflectionHelper.GetMethod<MyClass>(mc => mc.AddThing);
MethodInfo-MethodInfo=ReflectionHelper.GetMethod(mc=>mc.AddThing);
因此,如果ReflectionHelper事先知道参数计数和返回类型,那么答案将很简单——例如,如果它没有参数和返回字符串:

public static MethodInfo GetMethod<T, TReturn>(Expression<Func<T, Func<TArg, TReturn>>> expr)
{
    return ((MethodCallExpression)expr.Body).Method;
}
publicstaticmethodinfo-GetMethod(Expression-expr)
{
return((MethodCallExpression)expr.Body).Method;
}
除了我事先不知道参数计数/返回类型之外,我想避免用20个重载来滥发它,这些重载覆盖了大多数情况,但不是所有情况


那么,我该怎么做呢?

您还没有在lambda
mc=>mc.AddThing中指定一个方法-您已经指定了一个方法组

您可以做的是在表达式中编写一个方法调用——尽管它永远不会被执行,所以参数只需指定您想要的重载

所以,要使用它,你可以写:

MethodInfo mi = GetMethod<MyClass>( mc => mc.AddThing( null ) );

与表达式检查一样,如果lambda不是预期的形式,则很容易出现运行时错误,但这是摆脱“神奇”字符串的正确方向。

我现在使用的解决方法,我称之为“垃圾邮件方法”,虽然很难看,但在有限的场景中起作用:

public class ReflectionHelper<T>
{
    public MethodInfo GetMethod<TA1>(Expression<Func<T, Func<TA1>>> expr)
    {
        return ((MethodCallExpression)expr.Body).Method;
    }
    public MethodInfo GetMethod<TA1, TA2>(Expression<Func<T, Action<TA1, TA2>>> expr)
    {
        return ((MethodCallExpression)expr.Body).Method;
    }
    public MethodInfo GetMethod<TA1, TA2, TA3>(Expression<Func<T, Action<TA1, TA2, TA3>>> expr)
    {
        return ((MethodCallExpression)expr.Body).Method;
    }
    . . . // And more
}
公共类ReflectionHelper
{
公共方法信息获取方法(表达式表达式表达式)
{
return((MethodCallExpression)expr.Body).Method;
}
公共方法信息获取方法(表达式表达式表达式)
{
return((MethodCallExpression)expr.Body).Method;
}
公共方法信息获取方法(表达式表达式表达式)
{
return((MethodCallExpression)expr.Body).Method;
}
…//还有更多
}
接下来,它将指定一长串具有各种参数计数的潜在操作和函数。这使我实际上可以像这样使用它:

(new ReflectionHelper<MyClass>()).GetMethod<string>(mc => mc.SaySomething).Invoke("Hi");
(new ReflectionHelper()).GetMethod(mc=>mc.SaySomething.Invoke(“Hi”);
所以这很接近-我可以直接按名称调用方法,并且我确实避免为了这样做而传递假参数,但是我仍然被困在列出它的参数类型上-比我希望的更复杂。在具有多个同名方法重载的情况下,传递参数类型会将方法列表缩小到一个特定的重载


不过,我仍然对一些更简单的方法感兴趣,它可以采用我问题中的方法。在方法重载的情况下,它是模糊的,但是标准的.GetMethod(string)也是模糊的。

如果你不知道它接受的参数,你打算传递什么到方法中来尝试调用它?@Johnny5我不知道怎么做。调用它时仍然需要一个固定的签名,或者至少需要一个符合提供的参数的签名。@Servy ReflectionHelper不知道它接受的参数,但调用方法很可能知道。无法在注释中用干净的代码回答,但基本上是ReflectionHelper.GetMethod(mc=>mc.MyMethod.Invoke(“Hi”);//我们知道MyMethod只有一个参数,我们在这里调用GetMethod,但是GetMethod本身更灵活,可以在各种情况下使用,因为它不知道将使用的方法的结构。这是朝着正确方向迈出的一步-我不喜欢为了指定方法而传递假参数,虽然输入会稍微简单一些,但与我在下面发布的类似答案相比,它需要更多IDE的帮助。然而,不幸的是,这两个答案都没有让我达到目标。
(new ReflectionHelper<MyClass>()).GetMethod<string>(mc => mc.SaySomething).Invoke("Hi");