(for LISP hackers in short: I'm looking for the LISP-quote equivalent in C#)
I'm trying to write a meaningful ToString-method for a class which has a Func as member. Experiened API-users can set this member via setter-method like
myClassObject.SetFunction( (x) => x*x );
Now, when I use the ToString-method on the member it only returns
System.Func<double,double>
which is not very helpful. What would be helpful is
"(x) => x*X"
Is there any (preferable easy) way to do that?
Thanks for any help or comments.
Edit: corrected some typos
Expression<Func<double,double>> expr = x => x * x;
string s = expr.ToString(); // "x => (x * x)"
If you're willing to store your delegate as an expression, you can achieve what you want. The code would look something like this:
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 "";
}
In order to actually use the lambda expression, you have to compile it first. Storing it in a delegate means you only take that hit once.
Also, this approach means that users have to use a lambda, since method groups aren't convertible to Expression<Func<>>
. That's not a huge concern, though, since instead of passing MyMethod
, a user could pass x => MyMethod(x)
.
The calling code would look something like this:
myObject.SetFunc(x => 2*x);
Console.WriteLine(myObject.GetFuncText());
One final note is that the above sample is not thread-safe, so if you expect to have the methods called from multiple threads, some sort of synchronization would be appropriate.
None that I know of since that string has never entered the system, only IL was somehow generated and stored with a reference... you would need to "decompile" the IL to some meaningful string...
With CodeExpression
there is possibility to call GenerateCodeFromExpression
via an instance of CodeDomProvider
which has built-in implementations for C# / VB / JScript... but I would be surprised if that met your needs...
Another option: With Expression
you could use ToString()
- this works with LambdaExpression
too since that is just a descendant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With