Can I transform a Func<T> into an Expression<T>? [duplicate] - c#

Going from a lambda to an Expression is easy using a method call...
public void GimmeExpression(Expression<Func<T>> expression)
{
((MemberExpression)expression.Body).Member.Name; // "DoStuff"
}
public void SomewhereElse()
{
GimmeExpression(() => thing.DoStuff());
}
But I would like to turn the Func in to an expression, only in rare cases...
public void ContainTheDanger(Func<T> dangerousCall)
{
try
{
dangerousCall();
}
catch (Exception e)
{
// This next line does not work...
Expression<Func<T>> DangerousExpression = dangerousCall;
var nameOfDanger =
((MemberExpression)dangerousCall.Body).Member.Name;
throw new DangerContainer(
"Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
ContainTheDanger(() => thing.CrossTheStreams());
}
The line that does not work gives me the compile-time error Cannot implicitly convert type 'System.Func<T>' to 'System.Linq.Expressions.Expression<System.Func<T>>'. An explicit cast does not resolve the situation. Is there a facility to do this that I am overlooking?

Ooh, it's not easy at all. Func<T> represents a generic delegate and not an expression. If there's any way you could do so (due to optimizations and other things done by the compiler, some data might be thrown away, so it might be impossible to get the original expression back), it'd be disassembling the IL on the fly and inferring the expression (which is by no means easy). Treating lambda expressions as data (Expression<Func<T>>) is a magic done by the compiler (basically the compiler builds an expression tree in code instead of compiling it to IL).
Related fact
This is why languages that push lambdas to the extreme (like Lisp) are often easier to implement as interpreters. In those languages, code and data are essentially the same thing (even at run time), but our chip cannot understand that form of code, so we have to emulate such a machine by building an interpreter on top of it that understands it (the choice made by Lisp like languages) or sacrificing the power (code will no longer be exactly equal to data) to some extent (the choice made by C#). In C#, the compiler gives the illusion of treating code as data by allowing lambdas to be interpreted as code (Func<T>) and data (Expression<Func<T>>) at compile time.

private static Expression<Func<T, bool>> FuncToExpression<T>(Func<T, bool> f)
{
return x => f(x);
}

What you probably should do, is turn the method around. Take in an Expression>, and compile and run. If it fails, you already have the Expression to look into.
public void ContainTheDanger(Expression<Func<T>> dangerousCall)
{
try
{
dangerousCall().Compile().Invoke();;
}
catch (Exception e)
{
// This next line does not work...
var nameOfDanger =
((MemberExpression)dangerousCall.Body).Member.Name;
throw new DangerContainer(
"Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
ContainTheDanger(() => thing.CrossTheStreams());
}
Obviously you need to consider the performance implications of this, and determine if it is something that you really need to do.

If you sometimes need an expression and sometimes need a delegate, you have 2 options:
have different methods (1 for each)
always accept the Expression<...> version, and just .Compile().Invoke(...) it if you want a delegate. Obviously this has cost.

NJection.LambdaConverter is a library that converts a delegate to an expression
public class Program
{
private static void Main(string[] args) {
var lambda = Lambda.TransformMethodTo<Func<string, int>>()
.From(() => Parse)
.ToLambda();
}
public static int Parse(string value) {
return int.Parse(value)
}
}

You can go the other way via the .Compile() method however - not sure if this is useful for you:
public void ContainTheDanger<T>(Expression<Func<T>> dangerousCall)
{
try
{
var expr = dangerousCall.Compile();
expr.Invoke();
}
catch (Exception e)
{
Expression<Func<T>> DangerousExpression = dangerousCall;
var nameOfDanger = ((MethodCallExpression)dangerousCall.Body).Method.Name;
throw new DangerContainer("Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
var thing = new Thing();
ContainTheDanger(() => thing.CrossTheStreams());
}

Expression<Func<T>> ToExpression<T>(Func<T> call)
{
MethodCallExpression methodCall = call.Target == null
? Expression.Call(call.Method)
: Expression.Call(Expression.Constant(call.Target), call.Method);
return Expression.Lambda<Func<T>>(methodCall);
}

JB Evain from the Cecil Mono team is doing some progress to enable this
http://evain.net/blog/articles/2009/04/22/converting-delegates-to-expression-trees

Change
// This next line does not work...
Expression<Func<T>> DangerousExpression = dangerousCall;
To
// This next line works!
Expression<Func<T>> DangerousExpression = () => dangerousCall();

Related

C#: log variable name and value using function expression

In code which regularly needs debug logging, I end up with large blocks of code such as:
int someVar = 1;
bool anotherVar = true;
//...
string lastVar = "foo";
// littered through the code
Log._Debug(
"arbitrary message string",
$"{nameof(someVar)} = {someVar} " +
$"{nameof(anotherVar)} = {anotherVar} " +
// ...
$"{nameof(lastVar)} = {lastVar} "
);
These debug blocks can sometimes be huge (20+ vars being logged) and they can occur dozens of times in a class making the whole thing completely unreadable. Sadly they're necessary - sometimes we need to send debug builds to users (they can't run debugger, it's easier just to get them to run the debug build and send us the logs). It's also old code base which is why it's such a freaking mess.
I'm trying to find a way to debloat the debug chunks in the code, just to make it less depressing to maintain lol.
In my quest to find cleaner syntax, I found https://stackoverflow.com/a/9801735 which shows how to get member name from a lambda function. Which made me wonder, is it possible to create something a bit like this...?
Log._Dump(
"arbitrary message string",
() => somevar,
() => anotherVar,
// ...
() => lastVar
);
So I tried creating a method using params as follows:
[Conditional("DEBUG")]
public static void _Dump(string message, params Func[] vars) {
// ^ what <T> do I use?
}
private static string GetMemberName<T>(Expression<Func<T>> memberExpression) {
// this would eventually return $"{memberName} = {memberValue}"
// which, btw, I have no idea if that's even possible yet
// but I didn't get that far as still trying to work out how to do
// the _Dump() method params above :/
MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
return expressionBody.Member.Name;
}
I don't know how to do params array of functions with varying return types.
I could potentially just make the params a string array and do the GetMemberName manually for each lambda, for example:
private string NV<T>(Expression<Func<T>> memberExpression) {
// ...code...
return $"{memberName} = {memberValue}";
}
Log._Dump(
"arbitrary message string",
NV(() => somevar),
NV(() => anotherVar),
// ...
NV(() => lastVar)
);
But that's adding boilerplate to the code again which is what I'm trying to avoid. Is there any way I can get it working without that extra NV() wrapper?
EDIT: It's really old codebase and we're stuck with .Net Framework 3.5 so limited to C# 6 or something like that.
C# 10 introduced [CallerArgumentExpression] (docs), a way to pass a string representation of the callers source code. So you could write a helper method;
public void Log<T>(T value, [CallerArgumentExpression("value")] string name=null)
=> Log($"{name} = {value}");
But you could also combine this with another new feature, [InterpolatedStringHandler] (docs) to log the name of any variable inside an interpolated string.
[InterpolatedStringHandler]
public ref struct DebugLogHandler
{
private readonly StringBuilder sb;
public DebugLogHandler(int literalLen, int formattedCount)
{
sb = new StringBuilder(literalLen);
}
public void AppendLiteral(string s) => sb.Append(s);
public void AppendFormatted<T>(T value, [CallerArgumentExpression("value")] string name=null)
{
sb.Append(name);
sb.Append("=");
sb.Append(value?.ToString());
}
public string BuildMessage() => sb.ToString();
}
public static void Log(string message) { ...TODO... }
public static void Log(DebugLogHandler builder)
=> Log(builder.BuildMessage());
var variableName = "value";
Log($"Something {variableName}");

Creating a Func<object[], object> Delegate from MethodInfo

After much research and searching on SO; I've failed to find an answer that encompasses my specific situation. I wish to add modding capabilities to my project; currently I use a 3rd-party C# API which can convert scripts written in a particular interpreted language (specifically the functions in these scripts) into C# delegates.
Is there a way to wrap all of the delegates I get from the 3rd party API, into the a generic Func Delegate? My thoughts (in code) follow...
//The goal signature for all 'imported' delegates
public delegate object GenericSignature(object[] args);
//A fictional example...
public class Program
{
public static void Main()
{
GenericSignature desiredFunc = GenerateFromArbitraryMethod(
Program.FictionalArbitraryMethod);
object retVal = desiredFunc(1, new object(), "If only this worked");
}
public static FictionalArbitraryMethod(int num, object stuff, string name)
{
//code from mod author would be here
}
}
//Attempt #1
//If my understanding about Delegate.CreateDelegate() is correct,
//this will not work...
public GenericSignature GenerateFromArbitraryMethod(Delegate d) {
MethodInfo mInfo = d.Method;
return (GenericSignature) Delegate.CreateDelegate(typeof(GenericSignature), mInfo);
}
//Attempt #2
//seems a bit... better?; I can do some validation, but how do I actually call the
//function represented by MethodInfo since it's signature is arbitrary?
public GenericSignature GenerateFromArbitraryMethod(Delegate d) {
MethodInfo mInfo = d.Method;
return delegate(object[] args) {
ParameterInfo[] pInfo = mInfo.GetParameters();
if(args.length != pInfo.length) {
throw new Exception("Argument count does not match");
}
for(int i = 0; i < args.length; i++) {
if(pInfo[i].ParameterType != args[i].GetType()) {
throw new Exception("Incorrect Type for argument");
}
}
//At a loss of how to do the following; fake psuedo-code follows
/*
Foreach(object currentArg in arg) {
d.AppendArgAndCast(currentArg);
}
return d.Call();
or...
return d(EachOrUnpackAndCast(args));
*/
};
}
Apologies if there are any errors in the syntax; I'm mainly trying to get across the concept of what I'm trying to achieve. Some additional notes:
Based on info from here; Unity supports .NET 3.5 features; so the solution I would use can leverage up to .NET 3.5.
It is ok if any suggested solution is 'slow/heavy' due to heavy use of reflection; as long as I can generate a delegate, which I can cache and just call many, many times (to amortize the initial delegate creation cost)
Delegate.DynamicInvoke() does not meet my project's performance requirements. My understanding is reflection APIs are used per DynamicInvoke() call. Using reflection one time to create the faster delegate is preferable.
You need to compile your own bytecode to cast each argument from object to the correct type.
If you can upgrade from .Net 2, Expression makes this very easy.
If not, you'll need to use ILGenerator, or a wrapper such as Sigil.

Using Delegate to execute code at the method entry and exit

I have code that does very repetitive things such as logging the method entry and exit. In between, I execute some business logic. Is there a way I could handle that with a Delegate?
Here is what I have so far. However, it is really restrictive due to the func parameters I must passing. Anybody has a better idea?
Func<Func<int>, int> logAction = new Func<Func<int>, int>(func =>
{
try
{
Console.WriteLine("Logging...");
return func();
}
finally
{
Console.WriteLine("End Logging...");
}
});
Postsharp is perfect for this- it is an Aspect Orientated Programming library that features compile time weaving, so it wont impact on performance like run time weaving. This probably doesn't explain much if your new to AOP but basically, it will allow you to declare logging on a method like this:
<Logging> //apply an aspect that will log entrance/exit of method
void MyMethod(params)
{
//do something that might throw an exception (or not)
}
For an example (and source code) on using postsharp for logging, see http://www.sharpcrafters.com/solutions/logging
It seems that one of the AOP frameworks could solve your issue.
private void LogAction(string title, Action action)
{
Logger.Write(string.Format("Entering %0", title));
action();
Logger.Write(string.Format("Leaving %0", title));
}
Sample usage with no return value:
LogAction("DoSomething", () => DoSomething());
Sample usage with return value:
int intResult = 0;
LogAction("Square", () => intResult = Square(4, 4));
The easiest way to do this is to wrap everything inside of an Action and then just execute that in a method
public void log(Action methodToExecute)
{
try
{
Console.WriteLine("Logging...");
methodToExecute();
}
finally
{
Console.WriteLine("End Logging...");
}
}
Then call it creating a generic action for your function
//no return
log(() => yourFunciton(optionalParmeters));
//return to something
log(() => someVar = yourFunction(optionalParameters));

Passing a random method as a parameter?

Is there any way in C# to pass a random method as a parameter?
To explain my question:
I want to write a simple Logger-Tool that reports the entering and leaving of a method with the passed arguments an the class and method name:
The log file I'm aiming at:
ENTERING: ClassOfDoom::MethodOfDoom( arg1={1} [int], arg2={true} [bool] )
LEAVING: ClassOfDoom::MethodOfDoom RETURNING 1 [int]
The code I have in mind:
class ClassOfDoom {
// Remeber: MethodOfDoom is a _random_ method with _random_ arguments
public int MethodOfDoom(int arg1, bool arg2) {
Log.Entering(this, this.MethodOfDoom, arg1, arg2);
...
return Log.Returing(this, this.MethodOfDoom, 1);
}
}
Is there a way to achieve this? Or isn't C# as flexible as that?
Thanks in advance!
You can make your logging function take a MethodBase argument and use MethodBase.GetCurrentMethod to pass the current method info as an argument.
Then, in the logger, you could check its properties Name and DeclaringType to get the method information. Also, passing parameters is easy by declaring a params object[] args parameter in the logging function:
public static void Entering(object obj, MethodBase methodInfo,
params object[] args) {
Console.WriteLine("ENTERING {0}:{1}", methodInfo.DeclaringType.Name,
methodInfo.Name);
...
}
I'm not sure I entirely understand your question, but if you are trying to make a call to Log.Entering and Log.Returning inside an arbitrary (random) method and using the method's actual parameters, you should check out PostSharp. It will allow you to inject code in a method body and then do some work based on the reflected method information you get from the .NET framework (and the actual parameters passed to the method at runtime).
You could do it with Expression easily enough - it would look something like:
Log.Capture(() => this.MethodOfDoom(arg1, arg2));
Here's an example; I've been a bit lazy using Compile().DynamicInvoke() to read the arg-values - for real code I'd try to read it more directly:
using System;
using System.Diagnostics;
using System.Linq.Expressions;
class Program
{
DateTime MethodOfDoom(string s, int i)
{
return DateTime.Today;
}
public void RunTest()
{
int i =123;
Log.Capture(() => this.MethodOfDoom("abc", i));
}
static void Main()
{
new Program().RunTest();
}
}
static class Log
{
public static T Capture<T>(Expression<Func<T>> method)
{
MethodCallExpression mce = method.Body as MethodCallExpression;
if (mce == null) throw new InvalidOperationException(
"Method-call expected");
string name = mce.Method.Name;
try
{
int i = 0;
foreach(var param in mce.Method.GetParameters())
{
object argValue = Expression.Lambda(mce.Arguments[i++])
.Compile().DynamicInvoke();
Trace.WriteLine(param.Name + "=" + argValue, name);
}
Trace.WriteLine("ENTERING", name);
T result = method.Compile().Invoke();
Trace.WriteLine("EXITING: " + result, name);
return result;
}
catch (Exception ex)
{
Trace.WriteLine("EXCEPTION: " + ex, name);
throw;
}
}
}
If widely used in your code, this scenario is best implemented using Aspect Oriented Programming (AOP) techniques. There are different frameworks that can be used (such as Spring.NET AOP), which you can use in your .NET application. Here is a reference article that might help you get started:
http://www.developer.com/lang/article.php/10924_3795031_2
The referenced article gives you the logging enter/exit scenario as an example.
I have used PostSharp to do this very thing before.

Writing code to fire the last method to throw an exception in a multi-threaded web app

I was writing some try-catch blocks for various methods today, and thought to myself it would be good to have utility method which would automatically call the method again for a number of times specified in a parameter, at a certain time.
However, I thought to myself, the method/property etc which will cause an exception will be at the top of the stacktrace (do property calls get put on the stacktrace?) in a single threaded application (so an application with no code relating to threading). So I can simply get the method name at the top and dynamically call it again.
So I would have code like:
string s = StackTrace.GetFrame(0).GetMethodName; (I can't remember the exact syntax).
With this method, I can execute it using an activator or one of several other ways.
But in a multi-threaded application, I could have several methods firing at once and I wouldn't know which one finishes first/last. So I can't expect a method for which I write a try-catch block to be at the top of the stack.
How would I go about achieving this?
Please don't do this. It's a really, really, really, really, really bad idea.
Maybe not as bad as deleting files randomly, if the hard drive runs out of room - but just about as bad.
While I question the need for an auto retrying mechanism (does randomly retrying really help you out in so many situations that you need a utility method?) - using StackTrace and Reflection is, at best, a terribly complicated solution.
Not that I suggest that anyone actually use this code, but I'd probably go with a delegate based approach to this particular problem:
public static class Extensions {
public static void Try(this Action a, int maxTries) {
new (Func<bool>(() => { a(); return true; })).Try(maxTries);
}
public static TResult Try<TResult>(this Func<TResult> f, int maxTries) {
Exception lastException = null;
for (int i = 0; i < maxTries; i++) {
try {
return f();
} catch (Exception ex) {
lastException = ex;
}
}
throw lastException;
}
}
Usage is a bit unorthodox, but fairly clear I think:
// Set a property
new Action(() => myObject.Property = 5).Try(5);
// With a return value
var count = new Func<int>(() => myList.Count).Try(3);
You can't inline a lambda to a method, but you could have a somewhat fluent interface:
Utilities.Try(
() => MyObject.Property = 5
).Repeat(5);
And multi line methods:
Utilities.Try(() => {
MyObject.Property1 = 5;
MyObject.Property2 = 6;
MyObject.Property3 = 7;
}).Repeat(5);
Mark's code is probably better, but here's mine...
If you really want to do something like this, I'd use code something like this. Yes, you still have to manually call it, but your idea of indiscriminately retrying ALL excepting methods is a really, really bad idea.
public class TryAgain
{
public delegate void CodeToTryAgain ();
public static void Repeat<E>(int count, CodeToTryAgain code) where E : Exception
{
while (count-- > 0)
{
try
{
code();
return;
}
catch (E ex)
{
Console.WriteLine("Caught an {0} : {1}", typeof(E).Name, ex.Message);
// ignoring it!
}
}
}
}
And then you'd call your failing method, ThrowTwice, or whatever you want to do, like this:
TryAgain.Repeat<MyException>(5, delegate()
{
ThrowTwice();
});
In this example, the Repeat method will ignore all exceptions of type MyException, trying to call ThrowTwice up to 5 times...
You can add your own sleeping and time-outs, and whatever.

Categories

Resources