C# Action lambda limitation - c#

Why does this lambda expression not compile?
Action a = () => throw new InvalidOperationException();
Conjecture is fine, but I would really appreciate references to the C# language specification or other documentation.
And yes, I know that the following is valid and will compile:
Action a = () => { throw new InvalidOperationException(); };
The context where I would use something like this is described on this blog post.

Hmm. I've got an answer, but it's not great.
I don't believe that there's a "throw" expression. There's a throw statement, but not just an expression. Compare this with "Console.WriteLine()" which is a method invocation expression with a void type.
As a parallel, you can't have a switch statement, or an if statement etc as the body of a lambda on its own. You can only have an expression or a block (section 7.14).
Is that any help?

Here's my take:
throw is a statement, not an expression.
And the reference:
12.3.3.11 Throw statements
For a statement stmt of the form
throw expr;
the definite assignment state of v
at the beginning of expr is the same
as the definite assignment state of v
at the beginning of stmt.
To explain the essence perhaps one should think about what an expression implies within the C# lambda construct. It is simply syntactic sugar for:
delegate () { return XXX; }
where XXX is an expression

You can't return or throw from an un-scoped lambda.
Think of it this way... If you don't provide a {}, the compiler determines what your implicit return value is. When you throw from within the lambda, there is no return value. You're not even returning void. Why the compiler team didn't handle this situation, I don't know.

All the references I can find, from here:
http://msdn.microsoft.com/en-us/library/ms364047(VS.80).aspx#cs3spec_topic4
show that you have two options:
Action a = () => { throw new InvalidOperationException(); };
or
Action a = () => throw new InvalidOperationException()
Note the missing ; on the end. Yes, it makes no sense to me either. The examples they give in the spec are:
x => x + 1 // Implicitly typed, expression body
x => { return x + 1; } // Implicitly typed, statement body
(int x) => x + 1 // Explicitly typed, expression body
(int x) => { return x + 1; } // Explicitly typed, statement body
(x, y) => x * y // Multiple parameters
() => Console.WriteLine() // No parameters
Dunno how much help that is - I can't tell what context you are using it in, and not putting a ; on the end makes no sense in C#
the difference may be that it's an expression body - not a statement - if it doesn't have the {}. Which means that your throw is not valid there, as it's a statement, not an expression!

Not a big surprise. Lambda expressions are an aspect of functional programming. Exceptions are an aspect of procedural programming. The C# mesh between the two styles of programming isn't perfect.

Related

Calling a void-parameter lambda gives compiler error

From this question: Lambda expression with a void input
I have the following very simple code:
int minutes = () => 9;
I get compiler error:
Cannot convert lambda expression to type 'int' because it is not a
delegate type
I've found several questions about this error but they're all about more specific issues. I actually want to give my lambda a body but thought I'd start simple first to check my syntax:
//I know this is a weird example
int minutes = ()=> { if(x==9) return 9; else return 5;}
From C# guide
A lambda expression is a block of code (an expression or a statement block) that is treated as an object. It can be passed as an argument to methods, and it can also be returned by method calls.
...
Lambda expressions are code that can be represented either as a delegate, or as an expression tree that compiles to a delegate.
That means lambda expression can be represented and can represent different things: delegate or expression tree.
Your expression
() => 9;
can be so many different things, as example
public class C {
delegate int IntDelegate();
public void M() {
Func<int> minutes = () => 9;
IntDelegate minutes2 = () => 9;
Expression<Func<int>> minutesExpression = () => 9;
Expression<IntDelegate> minutesExpression2 = () => 9;
}
}
So what do you want to use?
By the way, because of all that, you can't use var with them.
And you can see how c# compiler work under the hood for different lambda here-> lambda as delegate and expression tree

if (x is A) { // use x as A

In C# I sometimes have to do something if the object is of some type.
e.g.,
if (x is A)
{
// do stuff but have to cast using (x as A)
}
What would be really nice if inside the if block, we could just use x as if it were an A, since it can't be anything else!
e.g.,
if (x is A)
{
(x as A).foo(); // redundant and verbose
x.foo(); // A contains a method called foo
}
Is the compiler just not smart enough to know this or is there any possible tricks to get similar behavior
Can the Dlang effectively do something similar?
BTW, I'm not looking for dynamic. Just trying to write less verbose code. Obviously I can do var y = x as A; and use y instead of X.
In D, the pattern you'd usually do is:
if(auto a = cast(A) your_obj) {
// use a in here, it is now of type A
// and will correctly check the class type
}
For one statement (or chain-able calls) you can use (x as A)?.Foo() in C# 6.0+ as shown in Is there an "opposite" to the null coalescing operator? (…in any language?).
There is no multiple statements version in the C# language, so if you want you'll need to write your own. I.e. using Action for body of the if statement:
void IfIsType<T>(object x, Action<T> action)
{
if (x is T)
action((T)x);
}
object s = "aaa";
IfIsType<string>(s, x => Console.WriteLine(x.IndexOf("a")));
I believe this is a feature is under consideration for C# 7. See the Roslyn issue for documentation, specifically 5.1 Type Pattern:
The type pattern is useful for performing runtime type tests of reference types, and replaces the idiom
var v = expr as Type;
if (v != null) { // code using v }
With the slightly more concise
if (expr is Type v) { // code using v }`
As for Dlang, I would reference their if statement syntax documentation here.

what is the use of ()=> in silverllight

Can you say what is the use of the ()=> and =>? I saw this in a code. I did not get any reference for this.
this.Dispatcher.BeginInvoke(()=>
{
//some thing..
};
=> is the lambda operator in C# and is read as "goes to". A lambda expression is an anonymous function and can be used to create a delegate.
Your example takes no arguments as indicated by the empty parens preceding the lambda operator. A lambda expression with one argument might look like this:
n => n.toString()
That expression would return the string representation of n, when invoked. A lambda expression can have multiple arguments as well, contained in parentheses:
(n, f) => n.toString(f)
A common use would be in a Func<T>:
Func<int, string> getString = n => n.toString();
int num = 7;
string numString = getString(num);
This is, of course, a silly example, but hopefully helps to illustrate its use.
This notation is that of a lambda expression which takes no argument. If the lambda expression made use of arguments they would be declared in the empty set of parenthesis as in say...
this.Dispatcher.BeginInvoke((x, y) => { do some' with x and/or y }, 12, somevar);
In a nutshell, lambda expressions allows creating "nameless" functions, right where they are needed.
In the example of the question, the BeginInvoke() method requires its first parameter to be a delegate (a "pointer to a method"), which is exactly what this lambda expression provides.
It's a lambda expression that has no parameters.
Check out this page http://codebetter.com/karlseguin/2008/11/27/back-to-basics-delegates-anonymous-methods-and-lambda-expressions/
If you don’t have any parameters, like in our example, you use empty
paranthesis:
() => {…}

What does "=>" mean?

Forgive me if this screams newbie but what does => mean in C#? I was at a presentation last week and this operator (I think) was used in the context of ORM. I wasn't really paying attention to the specifics of syntax until I went back to my notes.
In C# the lambda operator is written "=>" (usually pronounced "goes to" when read aloud). It means that the arguments on the left are passed into the code block (lambda function / anonymous delegate) on the right.
So if you have a Func or Action (or any of their cousins with more type parameters) then you can assign a lambda expression to them rather than needing to instantiate a delegate or have a separate method for the deferred processing:
//creates a Func that can be called later
Func<int,bool> f = i => i <= 10;
//calls the function with 12 substituted as the parameter
bool ret = f(12);
Since nobody mentioned it yet, in VB.NET you'd use the function keyword instead of =>, like so:
dim func = function() true
'or
dim func1 = function(x, y) x + y
dim result = func() ' result is True
dim result1 = func1(5, 2) ' result is 7
It's shorthand for declaring a lambda.
i => i++
is (sort of) the same as writing:
delegate(int i)
{
i++;
}
In the context of:
void DoSomething(Action<int> doSomething)
{
doSomething(1);
}
DoSomething(delegate(int i) { i++; });
//declares an anonymous method
//and passes it to DoSomething
which is (sort of) the same as writing:
void increment(int i)
{
i++;
}
Just without giving it a name, it allows you to declare a function in-line, known as an "anonymous" function.
When said aloud the operator is the lambda (goes to) operator which helps to define the anonymous delegate that you're defining in the lambda.
A common place to see this is with an event handler. You will often have a a page load type event that is handled by a lambda with the following code:
this.Loaded += (o, e) => {
// code
}
You've defined a method handling the Loaded event anonymously (it doesn't have a name) by using a lambda expression. It would read as "o, e goes to ... method definition with foo."
This is the "lambda operator", and you read it as "goes to". Say you had the statement:
doSomething(x => x + " hi");
You can replace the "=>" in your mind with this:
doSomething(delegate (string x) { return x + " hi" });
As you can see, it offers a heck of a shorthand. The compiler figures out the type of the variable that you're passing, and allows you to get rid of the function signature and bracketing for the code that you're passing the signature variables into.
It's a lambda operator, part of a lambda expression.
All lambda expressions use the lambda
operator =>, which is read as "goes
to". The left side of the lambda
operator specifies the input
parameters (if any) and the right side
holds the expression or statement
block. The lambda expression x => x *
x is read "x goes to x times x."
It's syntax to declare an anonymous function, known in C# as a "lambda expression."
For example, (int p) => p * 2 represents a function that takes an integer and multiplies it by two.

delegate keyword vs. lambda notation

Once it is compiled, is there a difference between:
delegate { x = 0; }
and
() => { x = 0 }
?
Short answer : no.
Longer answer that may not be relevant:
If you assign the lambda to a delegate type (such as Func or Action) you'll get an anonymous delegate.
If you assign the lambda to an Expression type, you'll get an expression tree instead of a anonymous delegate. The expression tree can then be compiled to an anonymous delegate.
Edit:
Here's some links for Expressions.
System.Linq.Expression.Expression(TDelegate) (start here).
Linq in-memory with delegates (such as System.Func) uses System.Linq.Enumerable. Linq to SQL (and anything else) with expressions uses System.Linq.Queryable. Check out the parameters on those methods.
An Explanation from ScottGu. In a nutshell, Linq in-memory will produce some anonymous methods to resolve your query. Linq to SQL will produce an expression tree that represents the query and then translate that tree into T-SQL. Linq to Entities will produce an expression tree that represents the query and then translate that tree into platform appropriate SQL.
I like Amy's answer, but I thought I'd be pedantic. The question says, "Once it is compiled" - which suggests that both expressions have been compiled. How could they both compile, but with one being converted to a delegate and one to an expression tree? It's a tricky one - you have to use another feature of anonymous methods; the only one which isn't shared by lambda expressions. If you specify an anonymous method without specifying a parameter list at all it is compatible with any delegate type returning void and without any out parameters. Armed with this knowledge, we should be able to construct two overloads to make the expressions completely unambiguous but very different.
But disaster strikes! At least with C# 3.0, you can't convert a lambda expression with a block body into an expression - nor can you convert a lambda expression with an assignment in the body (even if it is used as the return value). This may change with C# 4.0 and .NET 4.0, which allow more to be expressed in an expression tree. So in other words, with the examples MojoFilter happened to give, the two will almost always be converted to the same thing. (More details in a minute.)
We can use the delegate parameters trick if we change the bodies a little bit though:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
But wait! We can differentiate between the two even without using expression trees, if we're cunning enough. The example below uses the overload resolution rules (and the anonymous delegate matching trick)...
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
Ouch. Remember kids, every time you overload a method inherited from a base class, a little kitten starts crying.
In the two examples above there's no difference, zero.
The expression:
() => { x = 0 }
is a Lambda expression with statement body, so it can't be compiled as an expression tree. In fact it doesn't even compile because it needs a semicolon after 0:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
Amy B is correct. Note that there can be advantages to using expression trees. LINQ to SQL will examine the expression tree and convert it to SQL.
You can also play tricks with lamdas and expression trees to effectively pass the names of class members to a framework in a refactoring-safe way. Moq is an example of this.
There is a difference
Example:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
And I replace with lambda:(error)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Some basics here.
This is a anonymous method
(string testString) => { Console.WriteLine(testString); };
As anonymous methods do not have names we need a delegate in which we can assign both of these methods or expressions. e.g.
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
Same with the lambda expression. Usually we need a delegate to use them
s => s.Age > someValue && s.Age < someValue // will return true/false
We can use a func delegate to use this expression.
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);

Categories

Resources