(简称LISP黑客:我正在寻找C#中的LISP-quote等价物)
我正在尝试为一个有Func作为成员的类编写一个有意义的ToString方法。经验丰富的API用户可以通过setter-method设置此成员,如
myClassObject.SetFunction( (x) => x*x );
现在,当我在成员上使用ToString方法时,它只返回
System.Func<double,double>
这不是很有帮助。有用的是
"(x) => x*X"
有没有(最好的简单)方法呢?
感谢您提供任何帮助或意见。
编辑:更正了一些拼写错误
答案 0 :(得分:8)
Expression<Func<double,double>> expr = x => x * x;
string s = expr.ToString(); // "x => (x * x)"
答案 1 :(得分:1)
我知道没有,因为该字符串从未进入系统,只有IL以某种方式生成并存储了引用...您需要将IL“反编译”为一些有意义的字符串......
使用CodeExpression
,可以通过GenerateCodeFromExpression
的实例调用CodeDomProvider
,该实例具有C#/ VB / JScript的内置实现......但如果有的话,我会感到惊讶满足了你的需求......
另一种选择:使用Expression
,您可以使用ToString()
- 这也适用于LambdaExpression
,因为这只是一个后代。
答案 2 :(得分:1)
如果您愿意将代理作为表达式存储,则可以实现您想要的目标。代码看起来像这样:
private Expression<Func<double, double>> myFunc;
private Func<double, double> cachedDelegate;
public void SetFunc(Expression<Func<double,double>> newFunc)
{
this.myFunc = newFunc;
this.cachedDelegate = null;
}
public double ExecFunc(double x)
{
if (this.myFunc != null)
{
if (this.cachedDelegate != null)
{
return this.cachedDelegate(x);
}
else
{
this.cachedDelegate = this.myFunc.Compile();
return this.cachedDelegate(x);
}
}
return 0.0;
}
public string GetFuncText()
{
if (this.myFunc != null)
{
return this.myFunc.ToString();
}
return "";
}
为了实际使用lambda表达式,必须先编译它。将其存储在委托中意味着您只能接受一次该命中。
此外,这种方法意味着用户必须使用lambda,因为方法组不能转换为Expression<Func<>>
。但这不是一个大问题,因为用户可以通过MyMethod
而不是传递x => MyMethod(x)
。
调用代码看起来像这样:
myObject.SetFunc(x => 2*x);
Console.WriteLine(myObject.GetFuncText());
最后要注意的是,上面的示例不是线程安全的,因此如果您希望从多个线程调用这些方法,那么某种同步将是合适的。