I'm reviewing another person's code and can't ask him... What does that line of C# code do?
It's a lambda expression that takes no parameter and returns true.
The equivalent anonymous delegate is:
delegate() { return true; };
Most likely the method requires a parameter of type Func<bool>, which is a generic delegate with the same signature as above code.
EDIT:
As noted by cdhowie, the above lambda can also be evaluated to an expression tree of type Expression<Func<bool>>.
Here's the equivalent expression tree:
var body = Expression.Constant(true);
Expression<Func<bool>> returnsTrueExpression = Expression.Lambda<Func<bool>>(body);
You can 'convert' it to an actual delegate by calling Compile()
Func<bool> returnsTrueFunc = returnsTrueExpression.Compile();
This is a lambda expression that always return true. This is a delegate that has functionality similar to this method
bool Test(){
return true;
}
The code reminds me of when you may want to stub or mock values in the early stages of creating unit tests.
You could have a class that has a method like:
bool result = SomeClass.RunSomeImportantProcess(Func<bool> process)
and in your tests you might want to do something as a stub like
Assert.IsTrue(SomeClass.RunSomeImportantProcess(() => true));
Its a lambda expression which doesn't take any parameter but returns true. Whether its required or not, you would have to provide more info to determine.
Related
I've searched on this, but don't really know how to word the question to get the answer so far I can't find anything on nested actions like this with Lambda expressions. I can find lots of help on passing lambda expressions as parameters where the parameter is a delegate and in fact I'm doing that lots in my code. It's the nested lambda expression that's giving me problems.
I have a class with a property of type
Action<Action<string,int>> myAction
and I want to assign it with a Lambda expression. I can do it without Lambda expressions using real methods that I have elsewhere in the code. I can also do something simple like
myAction = ((a) => { a("a string", 0); });
but I would like to asign the sub-action and the action in one Lambda. Something like...
myAction = (((s,i)=>{//sub-action body here})=> { //do something here});
But this syntax doesn't work. Is there a way to do this, or do I have to define my methods in advance and do it without a Lambda expression if I want to do this?
Action<Action<string, int>> myAction = a => (new Action<string, int>((s, i) => Console.WriteLine(i + s)))("hello", 1);
myAction(null); //1hello
Console.ReadLine();
though its equal to
Action<Action<string, int>> myAction = a => Console.Writeline("1hello");
you just ignore an argument
I have a function with this signature:
public DeleteCommand(IService service,
Func<bool> canExecute, Action<ContactModel> deleted)
and code which calls it:
Delete = new DeleteCommand(
Service,
()=>CanDelete,
I don't understand what ()=>CanDelete exactly means. Being a Func<bool> it must return some value.
()=>
means it has no input parameters. But what is the value returned? why there is no return
in the lambda? Something like ()=> return CanDelete?
An expression lambda, which is what you have shown, returns the result of the expression following the =>. The return keyword is inferred, and in fact cannot be explicitly included. A statement lambda (which is of the form () => { someStatements;}) does not infer a return value, and requires an explicit return if it is not void.
I have a function:
public void Execute(Expression<Action> expression)
{
var time = expression.Compile().Benchmark();
var msg = string.Format("{0} took {1} to complete",
ReflectionHelper.GetComponentCallDetails().ToString(),
time.ToString(#"hh\:mm\:ss\.ff"));
Logger.Info(msg);
}
The delegate that needs to be called is something like:
channels = GetAllChannelsImpl(maxResults);
I am relatively new to Expression Trees and cannot figure out a way to pass the Action delegate to the method.
I was able to do the same functionality using
public void Execute(Action action)
{
var time = action.Benchmark();
var msg = string.Format("{0} took {1} to complete",
ReflectionHelper.GetComponentCallDetails().ToString(),
time.ToString(#"hh\:mm\:ss\.ff"));
Logger.Info(msg);
}
and calling as
Execute(() =>
{
channels = GetAllChannelsImpl(maxResults);
});
But I wanted to use the Expression Tree based approach in order to eliminate the need to use the overhead of reflection to figure out the details of the method invoked to log it.
Can anyone suggest the right way to pass the expression tree for the above action delegate as a method parameter.
A lambda expression by itself does not have a type. The actual type it takes is inferred by the compiler depending on what you are trying to assign or cast to. With that said, any calls to your Execute() method using simple lambdas will be ambiguous since your lambda would be compatible as an Action or Expression<Action>. You would have to disambiguate this by explicitly casting to the type you expect.
// assign to a variable
Expression<Action> action1 = () => ...;
Execute(action1);
// cast
Execute((Expression<Action>)(() => ...));
// use the constructor
Execute(new Expression<Action>(() => ...));
It would be better IMHO to remove the ambiguous overload and rename one of the methods. I'd recommend renaming the expression overload to ExecuteExpression().
I'm using jqGrid to display some data to users. jqGrid has search functionality that does string compares like Equals, NotEquals, Contains, StartsWith, NotStartsWith, etc.
When I use StartsWith I get valid results (looks like this):
Expression condition = Expression.Call(memberAccess,
typeof(string).GetMethod("StartsWith"),
Expression.Constant(value));
Since DoesNotStartWith doesn't exist I created it:
public static bool NotStartsWith(this string s, string value)
{
return !s.StartsWith(value);
}
This works, and I can create a string and call this method like so:
string myStr = "Hello World";
bool startsWith = myStr.NotStartsWith("Hello"); // false
So now I can create/call the expression like so:
Expression condition = Expression.Call(memberAccess,
typeof(string).GetMethod("NotStartsWith"),
Expression.Constant(value));
But I get a ArgumentNullException was unhandled by user code: Value cannot be null.
Parameter name: method error.
Does anyone know why this doesn't work or a better way to approach this?
You're checking for method NotStartsWith on type string, which doesn't exist. Instead of typeof(string), try typeof(ExtensionMethodClass), using the class where you put your NotStartsWith extension method. Extension methods don't actual exist on the type itself, they just act like they do.
Edit: Also rearrange your Expression.Call call like this,
Expression condition = Expression.Call(
typeof(string).GetMethod("NotStartsWith"),
memberAccess,
Expression.Constant(value));
The overload you are using expects an instance method, this overload expects a static method, based on the SO post you referred to. See here, http://msdn.microsoft.com/en-us/library/dd324092.aspx
i know the ask was answered, but another approach is available and simple:
Expression condition = Expression.Call(memberAccess,
typeof(string).GetMethod("StartsWith"),
Expression.Constant(value));
condition = Expression.Not(condition);
and... done! just have to negate the expression.
I have this method:
public void DoSomething<T>(Expression<Func<T, object>> method)
{
}
If this method is called like this:
DoSomething(c => c.SomeMethod(new TestObject()));
... how do I get the value of the parameter that was passed into SomeMethod()?
If the parameter is a value type, this works:
var methodCall = (MethodCallExpression)method.Body;
var parameterValue = ((ConstantExpression)methodCall.Arguments[0]).Value;
However, when I pass in a reference type, methodCall.Arguments[0] is a MemberExpression, and I can't seem to figure out how to write code to get the value out of it.
Here is the answer (inspired by Akash's answer):
LambdaExpression lambda = Expression.Lambda(methodCall.Arguments[0]);
var compiledExpression = lambda.Compile();
return compiledExpression.DynamicInvoke();
You will have to evaluate member expression manually, MemberExpression contains "Expression" which is the container object of Member specified, to do this you can crete Lamda of your arguement and compile and execute it.
LamdaExpression l = Expression.Lambda(methodCall.Arguments[0]);
var c = l.Compile();
var v = c.Invoke();
So whatever you pass, you will get it in "v" variable.
This isn't really a matter of value type or reference type - it's a matter of a constant expression or not-constant expression. I'm sure your existing code would fail if you called
DoSomething(c => c.SomeMethod(DateTime.Now));
as well.
Basically, the argument to the method is just an expression. It's not a value. You could potentially compile that expression and then execute it to get the value at that point in time, but it's important to understand that an expression isn't a value in itself. In the case of a constant expression it's easy, but taking the DateTime.Now example, by definition the evaluated value of the expression changes over time :)
What are you trying to do with the argument? What's the bigger picture here?
Firstly, what Jon said.
There are no values to get ahold of, it's all just expressions. What might be of interest is the NewExpression, which has a Constructor property; this property contains the reflected constructor that would be called if you compiled expression and ran the resulting delegate. You could manually invoke that constructor and get an instance of what the user was intending on instantiating.