When I write in my code
Action(() => someCombobox.Text = "x" )
I get this error:
Delegate 'System.Action<object>' does not take 0 arguments
Why?
This question is related to this one. I just want to understand why this error occurs.
You do not have to pass that as a constructor parameter:
Action a = () => someCombobox.Text = "x";
All you have to do is to declare an action and then use lambda expression to create it.
Alternatively you can pass the string to the action:
Action<string> a = (s) => someCombobox.Text = s;
a("your string here");
If you wish to create a System.Action delegate which has no parameters and does not return a value, simply change your code to this, removing the new Action([body]):
Action newAction = () => someCombobox.Text = "x";
This is because the lambda expression will return a new parameterless System.Action delegate for you. EDIT: as noted by Aliostad, () => someCombobox.Text = "x" will return either a lambda expression or an Action, depending on the type of the variable you are assigning it to.
EDIT: as Darin says, if you wish it to accept an argument then you need to pass that in when creating the lambda expression.
I think the answer here is the same as in the related question you are linking to: .NET 2.0 only has a definition for an Action delegate that takes a parameter.
The parameterless Action delegate was added in .NET 3.5, and requires a reference to System.Core.
Related
I decompiled a .net 4.6.1 project dll with dotpeek. After decompiling I have the following error:
CS1660 Cannot convert to 'Delegate' because type is not of delegate type
private void MainLogAdd(string s, System.Drawing.Color color)
{
this.logcol.Add(color);
this.lstLogBox.Invoke((delegate) (() =>
{
this.lstLogBox.Items.Add((object) ("[" + DateTime.Now.TimeOfDay.ToString().Substring(0, 8) + "] " + s));
this.lstLogBox.TopIndex = this.lstLogBox.Items.Count - 1;
}));
}
After change with new Action 'Action 1 does not contain a constructor that takes its arguments'
I believe it'll work out if you simply change (delegate) to (Action) instead
Before:
this.lstLogBox.Invoke((delegate) (() =>
After:
this.lstLogBox.Invoke((Action) (() =>
Here's an example:
Edit
You say you have a class called Action already and it's causing a conflict. You can use the full name:
this.lstLogBox.Invoke((System.Action) (() =>
Or you can create an alias by e.g. putting this at the top of your class:
using SystemAction = System.Action;
Then using the alias..
this.lstLogBox.Invoke((SystemAction) (() =>
Or you can rename your class :)
Replace (delegate) with new System.Action:
this.lstLogBox.Invoke(new System.Action(() =>
{
this.lstLogBox.Items.Add((object) ("[" + DateTime.Now.TimeOfDay.ToString().Substring(0, 8) + "] " + s));
this.lstLogBox.TopIndex = this.lstLogBox.Items.Count - 1;
}));
The Invoke method accepts a parameter of type Delegate, which is an abstract class and the base type for all delegates.
Lambda expressions may compile to expression trees (Expression<Func<...>>) or plain delegates (Action or Func). The C# compiler needs to know the exact type of the delegate, so it can generate the code for the lambda expression.
By the way, that's the problem with most C# decompilers. I had the best luck with ILSpy.
The value passed to .Invoke() needs to be an actual instantiated delegate type such as Action because the Windows Forms library was created before lambdas existed in C#. Instead of casting the lambda to a delegate like the decompiler wrote, it should read something like this:
this.lstLogBox.Invoke(new Action(() => { ... }));
Am I missing something or is it not possible to return a value from a lambda function such as..
Object test = () => { return new Object(); };
or
string test = () => { return "hello"; };
I get a build error "Cannot convert lambda expression to type 'string' because it is not a delegate type".
It's like this syntax assigns the lambda rather than the result of the lambda, which I did not expect.
I can achieve the desired functionality by assigning the function to a Func and calling it by name, but is that the only way?
Please no "why would you need to do this?" regarding my example.
Thanks in advance!
It’s possible but you are trying to assign a lambda to a string. – You need to invoke the lambda:
Func<string> f = () => { return "hello"; };
string test = f();
The error message actually says it all:
Cannot convert lambda expression to type 'string'
… that’s exactly the issue here.
If you want to invoke the lambda inline – but really: why? – you can do that too, you just need to first make it into a delegate explicitly:
string test = (new Func<string>(() => { return "hello"; }))();
I know what a func is, but not able to understand the following piece of code:
There's a simple property :
public Func<DomainFacade> BusinessFacadeFactory { get; set; }
And this is how the property is set:
this.BusinessFacadeFactory = () => new DomainFacade();
Now this way of setting the property, is it a Anonymous method or something else?
That's called a lambda expression.
It's a more-compact form of an anonymous method.
() => new DomainFacade() is a lambda expression
It is an unnamed method written in place of a delegate
The compiler converts it to a delegate instance
It's real format is
(parameter)=>expression or a statement block
Since the func requires a delegate to be assigned we can write a lambda expression instead of the delegate which would internally get converted to a delegate instance.
So,
() denotes a an empty parameter
new DomainFacade(); is the expression
that internally gets converted to delegate by the compiler
It is a lambda expression, which is shorthand for creating an anonymous method.
()
is the input parameters (i.e. none)
new DomainFacade();
is the method body.
() => new DomainFacade() is a lambda expression.
It is an inline method, returned as a delegate value.
This is a lambda expression as others have said. Here is what it would break down like this in long form:
this.BusinessFacadeFactory = () => new DomainFacade();
then
this.BusinessFacadeFactory = new delegate(){ return new DomainFacade()};
then
...
BusinessFacadeFactory = OnBusinessFacadeFactory;
...
private DomainFacade OnBusinessFacadeFactory()
{
return new DomainFacade()
}
I've noticed some examples of things that work and don't work when dealing with lambda functions and anonymous delegates in C#. What's going on here?
class Test : Control {
void testInvoke() {
// The best overloaded method match for 'Invoke' has some invalid arguments
Invoke(doSomething);
// Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type
Invoke(delegate { doSomething(); });
// OK
Invoke((Action)doSomething);
// OK
Invoke((Action)delegate { doSomething(); });
// Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type
Invoke(() => doSomething());
// OK
Invoke((Action)(() => doSomething()));
}
void testQueueUserWorkItem() {
// The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments
ThreadPool.QueueUserWorkItem(doSomething);
// OK
ThreadPool.QueueUserWorkItem(delegate { doSomething(); });
// The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments
ThreadPool.QueueUserWorkItem((Action)doSomething);
// No overload for 'doSomething' matches delegate 'WaitCallback'
ThreadPool.QueueUserWorkItem((WaitCallback)doSomething);
// OK
ThreadPool.QueueUserWorkItem((WaitCallback)delegate { doSomething(); });
// Delegate 'WaitCallback' does not take '0' arguments
ThreadPool.QueueUserWorkItem(() => doSomething());
// OK
ThreadPool.QueueUserWorkItem(state => doSomething());
}
void doSomething() {
// ...
}
}
Well that's a lot of examples. I guess my questions are the following:
Why does Invoke always refuse a lambda function or an anonymous delegate, yet ThreadPool.QueueUserWorkItem does just fine?
What the heck does "Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type" mean anyway?
Why does ThreadPool.QueueUserWorkItem accept an anonymous delegate with no parameters, but not a lambda expression with no parameters?
ThreadPool.QueueUserWorkItem has a specific delegate in its signature; Invoke just has Delegate. Lambda expressions and anonymous methods can only be converted to a specific delegate type.
It's just a bad error message. It means, "I don't know exactly which delegate type you're trying to convert to."
You're using an anonymous method without a parameter list at all which can be converted to any delegate type which doesn't use out/ref parameters. If you tried delegate() { ... } (i.e. an explicitly empty parameter list) then it wouldn't work. This "I don't care about parameters" ability of anonymous methods is the only feature they have which lambda expressions don't.
It's easiest to demonstrate all of this in the context of simple assignments, IMO:
// Doesn't work: no specific type
Delegate d = () => Console.WriteLine("Bang");
// Fine: we know the exact type to convert to
Action a = () => Console.WriteLine("Yay");
// Doesn't work: EventHandler isn't parameterless; we've specified 0 parameters
EventHandler e1 = () => Console.WriteLine("Bang");
EventHandler e2 = delegate() { Console.WriteLine("Bang again"); };
// Works: we don't care about parameter lists
EventHandler e = delegate { Console.WriteLine("Lambdas can't do this"); };
I was going through Jeffrey Palermo's book and came across this syntax.
private void InitializeRepositories()
{
Func<IVisitorRepository> builder = () => new VisitorRepository();
VisitorRepositoryFactory.RepositoryBuilder = builder;
}
What does it mean?
() => indicates a lambda expression that takes no arguments.
In general, it means a function with no arguments.
In this particular example, it creates an anonymous function with no arguments that returns a new VisitorRepository(); object every time.
Func<IVisitorRepository> stands for a delegate which takes no arguments and returns a IVisitorRepository. The creation of that delegate is a lambda function:
() //means no parameters
=> new VisitorRepository()// means it returns a new VisitorRepository
() is the place where you place your variables
Example a common event handled would look like (sender, args)
=> // means throw these parameter into this method
after => you can either drop a one line execution thing like new VisitorRepositor()
OR
you can place a whole function like
Func<IRepository> = (sender, args) =>
{
var myObject = (SomeObject)sender;
return new VisitorReposiroty { id = myObject.SomeId };
}
As other stated it's lambda expression and it really clears your code from method or function that handle a specific event.
Once you read them good it's really damn useful.
The () => syntax is a lambda expression. Lambdas were introduced in C# 3.0 and are used to define an anonymous method for a delegate.
The delegate is defined using the generic Func. So in this case the signature for the delegate is: no input parameters and one output parameter of type IVisitorRepository.
So on the left side of the => lambda array are the names of the input parameters. In case of no input parameters just write (). On the rightside of the => lambda is the code to return the output parameter, in this example: new VisitorRepository().
I suggest read more about lambda expressions in C# to fully understand this code. There is also a generic delegate involved, so you need understanding of Generics and Delegates as well.
Func is a delegate without parmeter and with an IVisitorRepository return value.
() => is a lambda expression creating an anonymous method.
new VisitorRepository() is the content of this anonymous method.
so this line is creating a delegate which is pointing to a anonymous method, which is returning an instance of VisitorRepository.
Func<IVisitorRepository> builder = () => new VisitorRepository()
In the next line, you set the value of a static property to this just created delegate.
VisitorRepositoryFactory.RepositoryBuilder = builder;
After this you can use the property to call the anonymous method, which is creating a new instance of VisitorRepository.
IVisitorRepository repository = VisitorRepositoryFactory.RepositoryBuilder();
In this case, repository will be an instance of VisitorRepository.
It means a function takes no parameters, like:
delegate() {//}