What's it called when a method that takes a lambda expression as the parameter, such as Enumerable.Where, is invoked without actually declaring a variable or method parameter in the expression?
For example, I'm familiar with this lambda expression syntax:
public string GetDigits(string input)
{
return new String(input.Where(i => Char.IsDigit(i)).ToArray());
}
However, I was surprised to find out that this can also be written as:
public string GetDigits(string input)
{
return new String(input.Where(Char.IsDigit).ToArray());
}
What's going on in that second snippet, where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this syntax called?
Methods don't accept lambdas as parameters. They accept delegates as parameters. A lambda is just one way of creating a delegate.
Another way is supplying a method group, as is done in your second example, which can be converted to a delegate.
A similar way is to use the anonymous method feature. This was more or less replaced with lambdas when they were added though, so you don't see it much. Your example using that syntax would be:
Func<char, bool> predicate = delegate(char c) { return Char.IsDigit(c); };
Yet another way would be to create a delegate using Delegate.CreateDelegate. (This isn't something you see all that often though.)
A final way is to have a delegate variable that you got from somewhere else. (That somewhere else would have created the delegate using one of these other options.)
What's going on in that second snippet, where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this syntax called?
It's not being called. That's the whole point. We're trying to create a delegate. A delegate is an object that keeps track of a method to be invoked, and an object that it should be invoked on. You can then invoke the delegate and it will call the method that was used to create it. So here you're not calling IsDigit, you're creating a delegate that is pointing to the IsDigit method, and that will call it whenever that delegate is invoked.
When you use a lambda you're creating a new method, possibly in a new class, (neither of which have a name you can refer to, but they'll have one at runtime) and the body of that anonymous method will call IsDigit. The lambda then resolves to a delegate pointing to that anonymous method, which maintains the semantics of the other example of having a method that when called, calls an anonymous method which, in its implementation, calls IsDigit. It's adding an extra layer of indirection (that may or may not just get optimized out at runtime) to accomplish the same thing.
The signature of Enumerable.Where is:
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
This:
input.Where(i => Char.IsDigit(i))
is equivalent to writing:
Func<char, bool> temp = i => Char.IsDigit(i);
input.Where(temp);
so it creates an anonymous function with a parameter i that calls Char.IsDigit.
This:
input.Where(Char.IsDigit)
is equivalent to
Func<char, bool> temp = Char.IsDigit;
input.Where(temp);
that is equivalent to:
Func<char, bool> temp = new Func<char, bool>(Char.IsDigit);
input.Where(temp);
so it creates a delegate to Char.IsDigit and then passes it to input.Where.
So the second one removes the "man-in-the-middle" (the anonymous function). In this particular case it is "legal" because the i parameter of the anonymous function is passed "as is" to Char.IsDigit. It would have been different if it was:
input.Where(i => !Char.IsDigit(i))
in this case, you can't remove the man-in-the-middle (the anonymous function).
There is no name for all of this (or you could call the first "creating and passing a delegate to an anonymous function" and the second "creating and passing a delegate created from a method group"... but they aren't beautiful catchphrases, they are more a description of what you are doing)
Because the compiler will implicitly cast the method group to a delegate if it finds a single method that matches the expected signature, in this case a delegate taking a single char as input and returning a bool.
Your Where expects a Func<char, bool>, which is a delegate for methods that take a char argument and return a bool. Anything that matches this delegate is a valid argument for this Where.
The lambda you wrote initially matches this delegate by type inference: the compiler expects that i is char, based on the generic parameter of the enumerable source - and infers the return type as bool, because that's what the method call expression inside the lambda would return.
The Char.IsDigit method itself also matches this. Thus, referencing the method is another valid way of expressing the same thing. This is called a method group.
The semantic equivalence of these two possible arguments for Where also makes sense if you consider that for every lambda expression, the compiler generates an anonymous method and then passes that anonymous method where the delegate was expected.
To illustrate this, consider your original snippet:
Where(i => Char.IsDigit(i))
The above gets lowered by the compiler to:
bool AnAnonymousMethod(char i)
{
return Char.IsDigit(i);
}
and then:
Where(AnAnonymousMethod)
As you can see, the lambda syntax (in cases where you don't have captured variables, like here) is just syntactic sugar for writing an anonymous method and then using the method group of this newly written method as the argument wherever a compatible delegate is expected.
Related
Forgive me if this is a stupid question but I am not sure where to look. I have this code that compiles fine:
static int Main(string[] args)
{
var parserResult = CommandLine.Parser.Default.ParseArguments<Options>(args);
parserResult.WithParsed<Options>(options => OnSuccessfulParse(options));
parserResult.WithNotParsed<Options>(errs =>
{
var helpText = HelpText.AutoBuild(parserResult, h =>
{
return HelpText.DefaultParsingErrorsHandler(parserResult, h);
}, e =>
{
return e;
});
Console.WriteLine(helpText);
ReturnErrorCode = ErrorCode.CommandLineArguments;
});
return (int)ReturnErrorCode;
}
My query has to do with this line of code:
parserResult.WithParsed<Options>(options => OnSuccessfulParse(options));
I understand that with a Lambda Expression the value on the left of the => is the value and value on the right is the expression.
What exactly is options? Why does it compile? It works absolutely fine. But what is it?
I don't know if this helps:
I might be barking up the wrong tree with my understanding of this. I admit I am struggling with the concept. Any explanation appreciated.
I see several questions but I can't explain it in my situation.
Update
OnSuccessfulParse declaration is:
private static void OnSuccessfulParse(Options options)
The WithParsed code is provided here
Lambda expression is the delegate of type Action<Options>. It is a callback from the parser into your code to inform you that the parse has been successful, and pass you Options object obtained as the result of the parse.
As far as options goes, it's just a name that you picked for the parameter to be passed into OnSuccessfulParse method. It is completely unnecessary here - this method group equivalent call will compile and run just the same:
parserResult.WithParsed<Options>(OnSuccessfulParse);
Here is the definition of WithParsed<T> method from github project:
public static ParserResult<T> WithParsed<T>(this ParserResult<T> result, Action<T> action)
{
var parsed = result as Parsed<T>;
if (parsed != null) {
action(parsed.Value);
}
return result;
}
This method is rather straightforward: it takes parse result, tries casting it to a successful parse, and if the cast is valid, calls a delegate that you supply. The WithNotParsed<T> method casts to unsuccessful NotParsed<T> result, and makes a call if the cast is valid.
That's a C# (.Net) way of representing function blocks.
Essentially an Action<Type> is an invocable type that roughly means pass an instance of Type in and execute the block.
E.g. we can write
public void Do(){
this.CallStuff(s => Console.WriteLine(s)); // or you can use a method group and do this.CallStuff(Console.WriteLine);
}
public void CallStuff(Action<string> action){
var #string = "fancy!";
action(#string);
}
In this case the s type is string.
In your example there is a type called Options defined somewhere and it is passed into an action.
Additionally, if you look at decompiled code, anonymous method blocks passed to actions are compiled as static anonymous types inside your class (because c# does not support dynamic code blocks, like, for example, obj-c does).
Another thing to look into are Func<out type> -> these are essentially the same as Action<> except the LAST type in the generic definition is the type they return.
UPD
#elgonzo raises a good point - Action<> and Func<> are actually just delegates; meaning that you can define a real method and pass it along as an Action or Func and then no anonymous static class will be compiled.
However in practice you will see that a lot of code defines those inline, and then the in-line code block needs to reside within a method somewhere, so the compiler puts it into the statis anonymous class.
What exactly is options?
options is i/p parameter to delegate represented by lambda expression
Why does it compile?
Simply because it adheres all syntactical and semantic rules of compiler ;) Like (x)=>x+1 is lambda expression to represent Func<int,int> (there can be another delegate to match same signature as well)
If your method expects Func<int,int> as parameter and argument passed is (x)=>x+1 then compiler infers this as x of type int. Compiled IL code would be equivalent to passing instance of delegate as an argument to method. Like :
call((x)=>x+1) will be compiled to call(new Func<int,int>(myMethod)) where call method definition is :
void Call(Func<int,int> someparam) {}
But what is it?
I think above response should have addressed this query.
I'm a beginner in C#. I encountered below code snippet in my project. I do not understand how ViewHelper.IsInView has been called without passing any parameters. Could anyone explain me this. Thanks in advance.
public static class ViewHelper
{
public static bool IsInView(IFrameworkElement element)
{
----------
}
}
var Result = Views.Any(ViewHelper.IsInView);
The Any method accepts a delegate - a pointer to a function - of the form Func<T, bool>. Meaning it expects a method that accepts an element of the type of the collection (I'm guessing IFrameworkElement in your case) and returns a bool - which is exactly the signature of the IsInView method.
The Any method then executes this delegate on elements in the Views collection until it encounters one that returns true.
In C#, there is an implicit conversion from a "method group" to a delegate type. Essentially, when you write
Views.Any(ViewHelper.IsInView)
It translates into
Views.Any(new Func<IFrameworkElement, bool>(ViewHelper.IsInView))
What is being passed to Enumerable.Any is a delegate, the method is not being called at this point. If there are any views then Any will call that delegate with one or more of the views as the argument.
The delegate you're passing to Any has been created through something known as implicit method group conversion.
Views.Any is expecting a delegate of the type Func<IFrameworkElement, bool>, meaning it takes a single parameter of type IFrameworkElement and returns bool. You can create such a delegate from your method, as the signatures are compatible. This is how you would explicitly do this:
Func<IFrameworkElement, bool> predicate =
new Func<IFrameworkElement, bool>(ViewHelper.IsInView);
However, from C# 2.0 such a conversion can be done implicitly, meaning this code is exactly the same:
Func<IFrameworkElement, bool> predicate = ViewHelper.IsInView;
I'm looking to get hold of a method name from a lambda expression, I'm aware it can be done this way:
GetName(() => MethodA());
My issue is that if MethodA takes any args, you have to supply them just to satisfy the compiler about the expression (after all, how can it know you're not actually executing it?)
I'd like to be able to do:
GetName(() => MethodA);
Is there a way of doing this?
NOTE: This is not a duplicate, this is dealing with a Method Group and not an actual "invocation" of a method.
Certainly. If you have your GetName method take an Expression<Func<Action>> as a parameter, for example, then you can pass () => MethodA into it, as long as MethodA is convertible to the same delegate signature as Action.
void Main()
{
Expression<Func<Action>> x = () => Foo;
Expression<Func<Func<int>>> y = () => Foo2;
var xName = ((MethodInfo)((ConstantExpression)((MethodCallExpression)((UnaryExpression)x.Body).Operand).Object).Value).Name;
}
void Foo(){}
int Foo2(){return 0;}
You can write your GetName method to examine the given expression and extract out the name of the method group from it. However, there are two things you should keep in mind.
Even if your lambda expression appears to "call" a method, it's only an expression and won't actually generate a call to that method.
Trying to capture a method group this way will make it very difficult to distinguish between overloaded methods with the same name.
For that reason, I have to imagine you'd be better off using a more traditional approach that does involve a method call expression.
For the case, of a void-returning parameterless method, the signature of GetName could look like this:
string GetName(Expression<Func<Action>> methodExpression)
That Action in there is a problem, to make it work for methods with other signatures, you would need to add lots of overloads for other delegate types.
A solution to this is to make GetName generic and let the user specify the delegate type:
string GetName<T>(Expression<Func<T>> methodExpression)
…
GetName<Action>(() => MethodA)
The problem with this approach is that T can be any type, not just a delegate, so it's very easy to call this version of GetName incorrectly, especially since GetName(() => MethodB()) will often compile (specifically, when MethodB returns something), due to type inference.
And type constrains won't help you here, you can't write where T : Delegate.
I need to understand how a developer can make use of Action delegates and lambdas. I will give an example:
For example, using MOQ, you write something like:
var repoMock = new Mock<IMyInterface>();
repoMock.Setup(r => r.GetData()).Returns(new string[] {"one", "two", "three"});
My point is, how's the code inside "Setup" and "Returns" is making use of the input (lambda expression)?
If you look at the type signatures for the Moq methods, you will notice that Setup and Returns are actually doing to very different things. Returns takes a delegate (a Func<TResult> or a Func<T, TResult>), but Setup actually takes an Expression, which is a much more complex data type. More details about the difference between Func<T> (a delegate) and Expression<Func<T>> (an expression) can be found in this related answer. The rest of my answer will try to explain how Moq, specifically, uses those two different types for two different reasons. Hopefully that will at least get you started in how to use them in your own code.
Delegates, whether they be named, anonymous, or lambda expressions, are .NET's way of permitting functions to be used as a "first class" objects; that's just a fancy way of saying that delegates can be used in all the same ways that the primitive types: you can declare local delegates, pass delegates as parameters, and return delegates from methods. You "call" a delegate the same way you call any other function: you use the () syntax.
In your case, you used the overload of Returns that doesn't actually take a delegate, it simply takes an value that will be returned whenever the associated mocked method is called. However, there are overloads of Returns that do take delegates, so you could have equivalently written this:
.Returns(() => new string[] {"one", "two", "three"}};
or
.Returns(x => x.produceStringArray("one", "two", "three"));
In either case, the Returns method will be given a delegate, of the appropriate type, as a parameter. Internally, all Returns really does is to save the delegate as part of the mocked object instance. Later, when the mocked method gets called, the delegate is executed to return the correct value. While the real Moq internals are more complex that this, the basic idea is something like the following:
private Func<T> returnMe;
public void Returns<T>(Func<T> myDelegate)
{
this.returnMe = myDelegate;
}
public T Execute()
{
return this.returnMe();
}
As you can see, once you have a delegate, you can just call it like any other function; when the compiler sees a lambda expression somewhere that it expects a delegate, it compiles the lambda expression into an anonymous delegate and that's what gets passed into your method.
The Setup method, on the other hand, is far more complex. The lambda expression there is not being passed as a Func<T>, but as an Expression<Func<T>>. What this means is, the compiler is not compiling the lambda expression into a delegate, but rather, into an expression tree. The objects in an expression tree are special types of object that represent the various things that a method can do. Compilers produce expression trees out of your source code all the time, but usually those expression trees are immediately used to produce machine code. When the C# compiler compiles an Expression, however, it actually leaves the expression tree in it's "half-compiled" state. You can finish compiling an expression, and run the resulting code if you want, but that's not the only way they are used. Your program can also examine the expression tree and see all the details about what the code "would do" if it were compiled and run, and use that information however it wants.
When you call a Moq method like this:
moq.Setup(x => x.MyMethod(1, 2, 3)).Returns(true);
the Setup method can use the expression tree to figure out the name of the method, and the types and values of the parameters, that you wrote on the right-hand side of your lambda. In this case, Moq never executes your lambda expression, merely examines it. It creates an internal object that is associated with the specific method call you just set up, and records the various things you associate with that method (e.g. the Return calls.) Later on, when you use your mocked object in a unit test, Moq will intercept every method call you make on your object, and scan its list of set-up methods looking for one that matches the call, and produce whatever mocked-up behavior you've specified about that call.
It is like the Setup method calls (or stores a reference to, for future use) a method with parameter "r" which returns r.GetData() value.
Hey all, quick question on how to call this lambda or what it actually does..
public Composite CreateBuffCheckAndCast(string name, UnitSelectDelegate onUnit, CanRunDecoratorDelegate extra)
{
return new Decorator(
ret => Spells.CanBuff(name, onUnit(ret)) && extra(ret),
new Action(ret => Spells.Buff(name, onUnit(ret))));
}
Unfortunately don't have the rest of this class and haven't used Lambdas in a while.. Where does that "ret" variable come from? The calling function? Is it used to grab an IEnumerable I could see the compiler assigning it whatever type onUnit would accept..?
Solution:
ret => is used to transform Spells.CanBuff into a delegate type to be accepted by Decorator. The onUnit would also accept a delegate function parameter.
The ret variable is the parameter to the delegate (or expression tree) that the lambda expression is building. Note that the ret for the first lambda expression is a different ret to the one in the second lambda expression.
So, two delegates are created, and they are passed to the Decorator constructor, which presumably stores them to execute them later on. When each delegate is called, the caller will have to pass a value in which will be available as the ret parameter during the lambda expression's execution.
Without seeing what the signature of the Decorator constructor is, it's hard to say any more than that.
I'm not quite sure what the relevance of your second snippet of code is, I'm afraid.
A lambda is an anonymous function. So in your case, ret is the parameter to the function.
When you do say
Func<int, int> myFunc = (f) => f + 1;
You are defining an anonymous function that takes an int and returns it + 1. You are storing a reference to the anonymous function in the myFunc reference. This function has not executed, it's just been defined. You can later call the function whenever you like:
int a = myFunc(4); // a becomes 5
An Action<T> is a delegate that returns void and usually points to a lambda such as yours. a Func<T1, T2> is a delegate that takes a T1 and returns a T2, and also usually points to a lambda. There are other delegates defined for other methods that take more parameters such as Func<T1, T2, T3> and Action<T1, T2>
In your case you are handing the Decorator two anonymous functions. When it deems necessary, it will call them to do some work for it, and use the return value to further its own work.