0

I don't know if this has much sense, I'm just experimenting things to extend my knowledge (which is not much).

Is it possibly to store a Lambda expression into a variable for later use it?

This is what I've tried:

Private t As Thread = New Thread(ThreadLambda)

Dim ThreadLambda As Expressions.LambdaExpression = _
    Sub()
        If tb2.InvokeRequired Then
            tb2.BeginInvoke(Sub() tb2.Text = tb1.Text)
        Else
            tb2.Text = tb1.Text
        End If
    End Sub

That launchs this exception:

Lambda expression cannot be converted to 'System.Linq.Expressions.LambdaExpression' because 'System.Linq.Expressions.LambdaExpression' is not a delegate type.

UPDATE:

I'm trying to follow @大师 燈 Xi Huan instructions but this Class is giving me a compiler exception of InvalidOperationException, it says that the value cannot be null (What value!?)

Public Class Form1

    Private t As Threading.Thread = New Threading.Thread(ThreadLambda)

    Dim ThreadLambda As Threading.ThreadStart = _
        Sub()
            For x = 0 To 10 : Debug.WriteLine("test") : Next
        End Sub

End Class
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • `t` and `ThreadLambda` are both members of `Form1`. When you create an instance of `Form1`, `t` is created before `ThreadLambda`. At that point, `ThreadLambda` is `Nothing`. A simple fix is to declare `ThreadLambda` before `t`, or create `t` in the constructor of `Form1` – sloth Oct 22 '13 at 12:21

2 Answers2

1

System.Linq.Expressions.LambdaExpression is a "ordinary" type, not a delegate type; but you can use System.Action, which is a delegate type:

Dim ThreadLambda As Action = _
    Sub()
        If tb2.InvokeRequired Then
            tb2.BeginInvoke(Sub() tb2.Text = tb1.Text)
        Else
            tb2.Text = tb1.Text
        End If
    End Sub

Action matches your lambda because it does not take arguments, and does not return a value.


If you want to use the Thread constructor that accepts an parameter of the ThreadStart delegate type, use ThreadStart instead of Action:

Dim ThreadLambda As ThreadStart = _
    Sub()
        If tb2.InvokeRequired Then
            tb2.BeginInvoke(Sub() tb2.Text = tb1.Text)
        Else
            tb2.Text = tb1.Text
        End If
    End Sub
sloth
  • 99,095
  • 21
  • 171
  • 219
  • Thankyou, but then how to use the action here?: `Private t As Threading.Thread = New Threading.Thread(ThreadLambda)` – ElektroStudios Oct 22 '13 at 11:58
  • 1
    `Threading.Thread` expects a `ThreadStart`; since `ThreadStart` also does not expect any parameters nor a return value, you can declare `ThreadLambda` as `Dim ThreadLambda As ThreadStart = ...` – sloth Oct 22 '13 at 12:00
  • Sorry but I don't understand how I could use the Lambda Action into the declared thread, I can replace the `ThreadLambda` word here: New Thread(`ThreadLambda`) to write all the lambda code and it will works, then how I can use there the Action that you've helped me to store the Lambda? – ElektroStudios Oct 22 '13 at 12:05
  • Sorry, I don't understand your question. You can store your lambda expression in a variable like `Dim ThreadLambda As ThreadStart = Sub() ...whatever...` and later create a thread with `Private t As Thread = New Thread(ThreadLambda)`. – sloth Oct 22 '13 at 12:10
  • Now I've understood, but the ThreadStart is giving me a compiler exception, please could you see my update? – ElektroStudios Oct 22 '13 at 12:17
  • `t` and `ThreadLambda` are both members of `Form1`. When you create an instance of `Form1`, `t` is created before `ThreadLambda`. At that point, `ThreadLambda` is `Nothing`. A simple fix is to declare `ThreadLambda` before `t`, or create `t` in the constructor of `Form1` – sloth Oct 22 '13 at 12:21
  • That is almost the same I answered to you yesterday... http://stackoverflow.com/questions/19492251/lambda-multiline-as-thread-parameter/19494433#19494433 – Carlos Landeras Oct 22 '13 at 12:46
  • @CarlosLanderas While related, that question was different. It was about the OP not knowing how to create multiline lamda expressions, while this question is about assigning lambda expressions to a variable. – sloth Oct 22 '13 at 12:53
  • Because the Sub() End Sub() it's a delegate. And an Action is a delegate: http://stackoverflow.com/questions/11376657/what-is-the-difference-between-delegate-action-in-c-sharp – Carlos Landeras Oct 22 '13 at 12:54
1

A LambdaExpression is NOT a lambda. It is an expression that, when processed, will create a lambda. The same goes for any type of expression, not just lambda expressions. Check Why would you use Expression> rather than Func? for more.

A Lambda's actual type is either Action<> or Func<>, depending on whether it returns a result or not. The rest of the type arguments are the lambda's parameters.

So, for example this creates a lambda function that adds to numbers:

Func<int,int,int> f= (a,b)=>a+b;
var res1=f(5,4);
var res2=f(3,7);

While this creates a lambda that writes to the console:

Action<string> g= (txt)=>Console.WriteLine(txt);
g("This is a message);

BTW, you should consider using the newer Task methods to run your lambda instead of a naked thread, eg:

Task.Run(theLambda);
Community
  • 1
  • 1
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • Thankyou but it says that Run is not a member of Tasks, I'm on FW 4.0 – ElektroStudios Oct 22 '13 at 12:03
  • 2
    Then it's [Task.Factory.StartNew](http://msdn.microsoft.com/en-us/library/dd321439.aspx) with overloads that accept either actions or functions – Panagiotis Kanavos Oct 22 '13 at 12:04
  • *A LambdaExpression is NOT a lambda. It is an expression...* No, `LambdaExpression` is a type that represents a lambda expression, not an expression itself. – sloth Oct 22 '13 at 12:05
  • 1
    *A Lambda's actual type is either Action<> or Func<>* No, you can assign lambda expressions to other delegate types than `Action<>` and `Func<>`, as long as the signature fits. – sloth Oct 22 '13 at 12:08
  • 1
    @大师燈XiHuan a LambdaExpression [inherits](http://msdn.microsoft.com/en-us/library/system.linq.expressions.lambdaexpression.aspx) from Expression. So it IS an expression for all intents and purposes – Panagiotis Kanavos Oct 22 '13 at 12:12
  • @PanagiotisKanavos Just because it inherits from a class that is called `Expression` does not make it an expression from the language's point of view. The way you wrote your answer is ambiguous. The fact that there's a type called `LambdaExpression` that the OP uses in his question is orthogonal to the fact C# supports lambda expressions. You can't just assign a lambda expression (the language construct) to a `LambdaExpression` (the type) variable. That's the problem of the OP. – sloth Oct 22 '13 at 12:17