我有一个方法,它将一个表达式作为参数,因为我需要方法字符串名称,而且我不关心该方法的参数,是否可以这样做?
答案 0 :(得分:2)
我认为没有。但是,您可以创建一个通用辅助方法,代替参数:
public T Any<T>(){
return default(T);
}
你可以这样称呼它:
YourMethod((YourClass yc) => yc.SomeMethod(Any<SomeClass>(), Any<SomeOtherClass>());
答案 1 :(得分:2)
是的,这是可能的。这是一个概念验证测试。
private static T RunExpression<T>(Expression<Func<T>> run )
{
var callExpression = (MethodCallExpression) run.Body;
var procedureName = callExpression.Method.Name;
Trace.WriteLine(procedureName);
foreach (var argument in callExpression.Arguments)
{
Trace.WriteLine(argument);
}
Trace.WriteLine(callExpression.Arguments.Count);
// Some really wicked stuff to assign out parameter
// Just for demonstration purposes
var outMember = (MemberExpression)callExpression.Arguments[1];
var e = Expression.Lambda<Func<object>>(outMember.Expression);
var o = e.Compile().Invoke();
var prop = o.GetType().GetField("s");
prop.SetValue(o, "Hello from magic method call!");
Trace.WriteLine(run.Body);
return default(T);
}
[TestMethod]
public void TestExpressionInvocation()
{
var action = new MyActionObject();
string s = null;
RunExpression(() => action.Create(1, out s));
Assert.AreEqual("Hello from magic method call!", s);
}
答案 2 :(得分:2)
最简单的方法是使用表达式树:
void Main()
{
Console.Out.WriteLine(GetNameOfMethod(new Action(Main)));
Console.Out.WriteLine(GetNameOfMethod(new Func<Delegate, string>(GetNameOfMethod)));
Console.Out.WriteLine(GetNameOfMethod(new Func<int, short, long>(AddNumber)));
Console.Out.WriteLine(GetNameOfMethod(new Action<int, short>(SwallowNumber)));
}
string GetNameOfMethod(Delegate d){
return d.Method.Name;
}
long AddNumber(int x, short y){ return x+y; }
void SwallowNumber(int x, short y){}
的产率:
Main GetNameOfMethod AddNumber SwallowNumber
我使用它在http://storyq.codeplex.com上构建BDD框架。
答案 3 :(得分:1)
您可以在没有参数的情况下使用此方法,但需要括号(甚至为空),因为没有它们,您可以告诉编译器访问该名称的属性。
答案 4 :(得分:0)
您可以使用以下内容: (学分去klausbyskov) 但它不那么冗长。
此外,您还需要为各种参数列表提供重载。
[TestClass]
public class TestExpressions
{
public class MyClass
{
public bool MyMethod(string arg)
{
throw new NotImplementedException();
}
}
private static string UseExpression<T, Ta1>(Expression<Action<T,Ta1>> run)
{
return ((MethodCallExpression)run.Body).Method.Name;
}
[TestMethod]
public void TestExpressionParser()
{
Assert.AreEqual("MyMethod",
UseExpression<MyClass,string>((c,fakeString) => c.MyMethod(fakeString)));
}
}