MemberExpression可以返回Method吗?

本文关键字:Method 返回 MemberExpression | 更新日期: 2023-09-27 18:12:13

我想在c#中返回一个带有某种Lambda表达式的方法(或方法info)。

public class MyClass {
    public object ReturnSomething(string arg, int numericArg)
    {/*...*/}
}

然后,稍后,我想使用Lambda引用这个方法,像这样…

public static void Run<T>(T sourceObject, Expression<Func<T, object>> memberExpression, IEnumerable<object> parameters)
{
    var methodInfo = ((MemberExpression)memberExpression.Body).Member as MethodInfo;
    if (methodInfo == null)
        throw new ArgumentException("memberExpression must yield a method");
    /*...*/
}

我试过这样使用:

var myClassObject = new MyClass();
Run(myClassObject, o => o.ReturnSomething, new object["string arg", 1]);

但是我一直得到这个编译错误在我的表达式:

无法将方法组"ReturnSomething"转换为非委托类型"对象"。您是否打算调用该方法?

这在c#中可行吗?或者我应该放弃并传递一个带有方法名称的字符串,并使用反射来查找而不是使用MemberExpression?

MemberExpression可以返回Method吗?

T McKeown在上面问了一个正确的问题,当我在lambda表达式中提供参数很容易时,我正在使用动态执行。

我通过不做蠢事来解决这个问题。我没有返回实际的方法,而是将结构更改为一个内联执行的表达式。似乎比我原来要去的地方干净多了。

的目的是比较两个类似的类对象的执行,以确保它们都返回相同的值。这样做是因为我正处于重写过程中,希望确保我的新方法返回与旧方法相同。

我在这里结束了:

public static void CompareExecutions<TObject, TParameter, TReturn>(this TObject originalSource, TObject alternateSource, IEnumerable<TParameter> parameters, Func<TObject, TParameter, TReturn> testExpression)
    where TObject : class
    where TReturn : class
{
    var originalResults = new List<TReturn>();
    using (new Profile("Original Source"))
        foreach (var parameterSet in parameters)
            originalResults.Add(testExpression(originalSource, parameterSet));
    var alternateResults = new List<TReturn>();
    using (new Profile("Alternate Source"))
        foreach (var parameterSet in parameters)
            alternateResults.Add(testExpression(alternateSource, parameterSet));
    var comparer = new PropertyComparer<TReturn>();
    int errorCount = 0;
    for (int i = 0; i < parameters.Count(); i++)
    {
        if (!comparer.Equals(originalResults[i], alternateResults[i]))
        {
            errorCount++;
            Debug.WriteLine("^--- Mismatch for parameter {0}:'r'n't{1}", i, string.Join("'r'n't", parameters.ElementAt(i)));
        }
    }
    if (errorCount > 0)
        Assert.Fail("The results did not match for {0} items", errorCount);
}

我这样使用它:

public class OriginalClass
{
    public virtual ResultClass MyMethod(string argOne, int argTwo)
    {/*...*/}
}
public class DerivedClass: OriginalClass
{
    public override ResultClass MyMethod(string argOne, int argTwo)
    {/*New implementation of the original code...*/}
}
//[...]
public void TestTheseTwoClasses() {
    var original = new OriginalClass();
    var derivedClass = new DerivedClass();
    original.CompareExecutions(
        derivedClass,
        new[] {
            new {One = "First", Two=1},
            new {One = "Second", Two=2},
            new {One = "Third", Two=3}
        },
        (c,p) => c.MyMethod(p.One, p.Two)
    );
}