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?
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)
);
}