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
I'm trying to write a code analysis rule with roslyn.
Basically, I have to check whether an each of arguments which a Microsoft.Practices.Prism.Commands.DelegateCommand() is created is wrapped in try catch or not.
The main idea is collect all ObjectCreationExpressionSyntax objects of DelegateCommand class and check each constructor's argument if the first StatementSyntax is TryStatementSyntax or not.
Can you help me with getting all StatementSyntax from ArgumentSyntax ? Or may be you have an another approach ?
public IEnumerable<IdentifierInfo> Collect(SyntaxNode rootNode, SemanticModel semanticModel)
{
ObjectCreationExpressionSyntax[] objCreation = rootNode
.DescendantNodes()
.OfType<ObjectCreationExpressionSyntax>()
.Where(c=>(c.Type as IdentifierNameSyntax)?.Identifier.Value.ToString() == "DelegateCommand")
.ToArray();
foreach (var obj in objCreation)
{
var args = obj.ArgumentList.Arguments;
foreach (ArgumentSyntax arg in args)
{
var expession = arg.Expression;
var symbol = semanticModel.GetSymbolInfo(expession).Symbol as IMethodSymbol;
}
}
}
Bellow you can find what I actually compile for searching through:
public class Program
{
public delegate void MyDelegate();
public static void DelegateMethod() { try { } catch { } }
public static void Main(string[] args)
{
DelegateCommand del1 = new DelegateCommand(() => {try{}catch{}});
DelegateCommand del2 = new DelegateCommand(new Action(() => { }));
DelegateCommand del3 = new DelegateCommand(DelegateMethod);
var barInit = (Action)(DelegateMethod);
DelegateCommand del4 = new DelegateCommand(barInit);
ICommand test;
test = new Microsoft.Practices.Prism.Commands.DelegateCommand(() => { });
}
}
You start in a good way, but to handle it completely, its required more work.
Lets see in your example what we have
(The screenshot is from LINQ debugging feature from OzCode)
Here what I wrote is
var argsExpr = objCreation.Select(o => o.ArgumentList.Arguments.First())
As you can see in the right side of the window, we have a three types of syntax nodes in the arguments, so we don't have a general way to handle them all.
You have two ways to handle it.
Write method that get SyntaxNode and according to its type, check if the first statement is a try\catch statement
Write SyntaxWalker and visit relevant methods, and there, check if the first statement is a try\catch statement
For example to handle the first case which is ParenthesizedLambdaExpressionSyntax you need to write something like this (or by yourself or by overriding the appropriate Visit method of the SyntaxWalker)
public static bool IsTryStatement(ParenthesizedLambdaExpressionSyntax node)
{
return ((BlockSyntax) node.Body).Statements.First() is TryStatementSyntax;
}
This is just an example. In your real code you need to handle all cases.
For the IdentifierNameSyntax you need to get the method symbol first:
semanticModel.GetSymbolInfo(identifier).Symbol
Then you need to get the syntax node from DeclaringSyntaxReferences and use span, or you can use location of the symbol or any other way (ConstructFrom maybe).
I'm building up tooling for a piece of software and would like to be able save out the boolean expression in the source code that exists in a Debug.Assert (or Trace.Assert) call.
For example, if the program crashes with:
var x = -1;
Debug.Assert(x >= 0, "X must be non-negative", "some detail message");
I'd like to be able to get out the string "x >= 0" as well as the message and detail message.
I've looked into using a TraceListener, but TraceListener#Fail(string) and TraceListener#Fail(string, string) only can capture the message and detail message fields (which, in the case a developer does not include, leaves me with no easy way to report what went wrong).
I suppose it's possible to create a stack trace and read the particular line that failed and report that (assuming the source code is available), but this seems relatively fragile.
Thanks for your time!
You can use expressions to accomplish something rough:
public static class DebugEx
{
[Conditional("DEBUG")]
public static void Assert(Expression<Func<bool>> assertion, string message)
{
Debug.Assert(assertion.Compile()(), message, assertion.Body.ToString());
}
}
and use it like so:
var i = -1;
DebugEx.Assert(() => i > 0, "Message");
There are some down sides to this. The first is, you have to use a lambda, so that complicates the syntax a little bit. The second is since we are dynamically compiling things, there is a performance hit. Since this will only happen in Debug mode (hence the conditional), the performance loss won't be seen in Release mode.
Lastly, the output isn't pretty. It'll look something like this:
(value(WindowsFormsApplication1.Form1+<>c__DisplayClass0).i > 0)
There isn't a whole lot you can do about this. The reason this happens is because of the closure around i. This is actually accurate since that is what it gets compiled down into.
I had already started typing an answer when #vcsjones posted his answer, so I abandoned mine, but I see there are some parts of it that are still relevant. Primarily with regards to formatting the lambda expression into something readable, So I will merge his with that part of my intended answer.
It uses a number of regular expressions to format the assertion expression, so that in many cases it will look decent (i.e. close to what you typed).
For the example given in #vcsjones answer it will now look like this:
Assertion '(i > 0)' failed.
public static class DebugEx
{
private static readonly Dictionary<Regex, string> _replacements;
static DebugEx()
{
_replacements = new Dictionary<Regex,string>()
{
{new Regex("value\\([^)]*\\)\\."), string.Empty},
{new Regex("\\(\\)\\."), string.Empty},
{new Regex("\\(\\)\\ =>"), string.Empty},
{new Regex("Not"), "!"}
};
}
[Conditional("DEBUG")]
public static void Assert(Expression<Func<bool>> assertion, string message)
{
if (!assertion.Compile()())
Debug.Assert(false, message, FormatFailure(assertion));
}
private static string FormatFailure(Expression assertion)
{
return string.Format("Assertion '{0}' failed.", Normalize(assertion.ToString()));
}
private static string Normalize(string expression)
{
string result = expression;
foreach (var pattern in _replacements)
{
result = pattern.Key.Replace(result, pattern.Value);
}
return result.Trim();
}
}
I've created a generic delegate and I want to assign to it a function without any arguments.
Is it possible?
Here is what I tried so far:
class Program
{
public delegate void TemplateDel<T>(T item);
public static void fWriteLetters(char[] p_cLetters)
{
for (int i = 0; i < p_cLetters.Length; i++)
Console.WriteLine(p_cLetters[i]);
}
void fNoArg()
{
Console.WriteLine("No arguments!");
}
static void Main(string[] args)
{
TemplateDel<char[]> l_dWriteLeters = new TemplateDel<char[]>(fWriteLetters);
TemplateDel<void> l_dNoArg = new TemplateDel<void>(fWriteLetters);
}
}
the last line of code doesn't compile...
No it is not possible.void is only valid in return types.You can't use it as a type in other contexts. (except the unsafe context)
You need add another overload for your delegate.
public delegate void TemplateDel();
Or simply use an Action.
As Selman22 notes in the other answer:
No it is not possible.
But there is another way, use a lambda to throw away the argument:
TemplateDel<bool> l_dNoArg = new TemplateDel<bool>(_ => fWriteLetters);
(Using _ as the identifier here matches F#'s wildcard – ignore this argument – syntax.)
While not helpful here, this kind of wrapper is helpful when arguments are not interested in are passed and saves writing an extra member just to ignore or re-arrange arguments.
I would like to get both the compiled Func(of boolean) and an
Expression( of Func(of boolean)) using a single parameter. I don't intend to modify
the expression tree. The only reason to take an Expression tree at all
is so i can print out the code that is being executed.
void Assert(Expression<Func<bool>> assertionExpression) {
if (!assertionExpression.Compile()())
{
throw new AssertFailedException(assertionExpression.ToString());
}
}
Is there any reasonable way to do this?
As a corrolarry, in the case of simple compiler generated expression trees, will the same instance always be passed as a parameter?
static Dictionary<Expression<Func<bool>>, Func<bool>> cache;
static void Assert(Expression<Func<bool>> assertionExpression) {
Func<bool> method = null;
if (!cache.TryGetValue(assertionExpression, out method)) {
cache.Add(assertionExpression, method = assertionExpression.Compile());
Console.WriteLine("cache insert");
}
else {
Console.WriteLine("cache hit");
}
if (!method())
{
throw new AssertFailedException(assertionExpression.ToString());
}
}
static void someCodeThatExecutesRegularly() {
Assert(()=>true);
}
public static void Main(string[] args, int argc)
{
someCodeThatExecutesRegularly();
someCodeThatExecutesRegularly();
someCodeThatExecutesRegularly();
}
Will the output be 'cache insert, 'cache hit', 'cache hit' or 'cache insert', 'cache insert', 'cache insert'.
For the first question, you can take the expression tree and compile it to get an executable version, although it will recompile each time so you would have to cache it.
static void Assert(Expression<Func<bool>> assertionExpression) {
var func = assertionExpression.Compile(); // if you call func() it will execute the expression
}
For your second question, it will be a new expression tree each time, so you will get "cache insert" "cache insert" "cache insert" etc...
To get it working with the cache and compiling you could possibly use .ToString() on the expression to get the string representation of the function, but this could cause very confusing issues if you have any closures because the string representation could be the same but the closed variables would be different, so if you do do this, USE WITH CARE!
I need to write a delegate function that can 'wrap' some while/try/catch code around a basic UDP call to verify the link.
I made it work for Func for a function that has no arguments, but I can't make it work for Action, which has an argument (but no return). I can't seem to pass in the argument in a logical way without the compiler complaining.
Am I going about this all wrong? I'm new to C# and I'm essentially trying to mimick the idea of a function pointer. Should I not be overloading this function? I know you can't overload delegates (I assume that's why Func and Action exist).
This works:
protected TResult udpCommand<TResult>(Func<TResult> command)
{
TResult retValue = default(TResult);
while (!linkDownFail)
{
try
{
retValue = command();
break;
}
catch
{
LinkStateCallBack(ip, getLinkStatus());
if (linkDownFail) throw new LinkDownException();
Thread.Sleep(100);
}
}
return retValue;
}
But this does not:
protected void udpCommand<T>(Action<T> command(T value))
{
while(!linkDownFail)
{
try
{
command(value);
break;
}
catch
{
LinkStateCallBack(ip, getLinkStatus());
if (linkDownFail) throw new LinkDownException();
Thread.Sleep(100);
}
}
return;
}
Calling convention (for one that works):
udpCommand<uint>(someUdpCommand);
If you want this to be generic enough to handle any number of arguments, try using the non-genernic Action delegate:
protected void udpCommand(Action command)
{
while(!linkDownFail)
{
try
{
command();
break;
}
catch
{
LinkStateCallBack(ip, getLinkStatus());
if (linkDownFail) throw new LinkDownException();
Thread.Sleep(100);
}
}
return;
}
In C# 3.0, you can call it like this:
udpCommand(() => noParameterMethod());
udpCommand(() => singleParameterMethod(value));
udpCommand(() => manyParameterMethod(value, value2, value3, value4));
In C# 2.0 it's a little uglier:
udpCommand(delegate { noParameterMethod(); });
udpCommand(delegate { singleParameterMethod(value); });
udpCommand(delegate { manyParameterMethod(value, value2, value3, value4); });
This gives you deferred execution without locking you into a particular method signature.
EDIT
I just notice I kinda stole Marc Gravell's comment... apologies Marc. To answer how you might reduce your duplication, you can have the Action method call the Func<T> method, like this:
protected void udpCommand(Action command)
{
udpCommand(() => { command(); return 0; });
}
I believe (and I may be wrong) that returning 0 is no more costly than (implicitly) returning void, but I may be way off here. Even it it does have a cost, it would only put a tiny itty bitty snoodge extra on the stack. In most cases, the additional cost won't ever cause you any grief.
Do you mean:
protected void udpCommand<T>(Action<T> command, T value) {...}
With calling:
udpCommand(someUdpCommand, arg);
Note that this may work better on C# 3.0, which has stronger generic type inference than C# 2.0.
I think you just need to take out the (T value) after 'command'.
Are you trying to do this ...
protected void udpCommand<T>(Action<T> command, T value)
{
while(!linkDownFail)
{
try
{
command(value);
// etc.
}
}
}
Then it would work like this ...
public void ActionWithInt( int param )
{
// some command
}
Action<int> fp = ActionWithInt;
udpCommand<int>( fp, 10 ); // or whatever.