C# method meaning [duplicate] - c#

This question already has answers here:
What does the '=>' syntax in C# mean?
(7 answers)
Closed 8 years ago.
so I am looking at this C# method
if (IsInDesignMode)
{
// Only runs in design mode
_dataService.GetMachine(_machines[0].Machine.SerialNumber, (machine, error) => //<-- this is what I am confused about
{
SelectedMachine = new MachineViewModel(machine);
});
}
I understand the if() statement and the SelectedMachine = new MachineViewModel(machine); line.
But I am confused about the commented line.
_dataService calls a GetMachine method passing in _machines[0].Machine.SerialNumber param and (machine, error) => {}. It is not an "equal or less than" statement right?.
It kinda looks like a Javascript code to me...?
Does the method say,
If IsInDesignMode {
dataservice.GetMachine(machine serial number, machine error is new MachineViewModel)
}
Can any one explain what => { } this is? thank you very much!

The part you are asking about is an anonymous method that uses a lambda expression. It is commonly used in callbacks.
When you write this
(machine, error) => { SelectedMachine = new MachineViewModel(machine); }
you are making a function that has no name (and therefore cannot be reused by name, like a regular method). It is very convenient in situations when you need to produce a piece of callable code that needs to be used only once, e.g. in callbacks.
Note that the method does not have to be anonymous: you could make an equivalent named method. However, an since the anonymous method is built in the context of the method where it is used, the variables from the context are available to it. Your anonymous method assigns SelectedMachine, which is probably a property of your class. In the same way, anonymous methods can access local variables as well, which is a very powerful mechanism of combining together a state and a piece of code that operates on it.

To be more precise. It is an Anonymous method using lambda expression.
the sign you are asking '=> { }' is called lambda expression.
Usually it is used with Delegate type like func, Action, predicate and others.
Have a look on the above types to make yourself more clear.

It is a lambda expression. Have a look on this page for more info: http://msdn.microsoft.com/en-us/library/bb397687.aspx

Related

C# lambda variable initialization [duplicate]

This question already has answers here:
What does the => operator mean in a property or method?
(7 answers)
Closed 7 years ago.
Today for the first time I seen something similar to this:
private string m => string.Empty;
using lambda to initialize a variable. Why doing it like this and what are the benefits?
It's called Expression-Bodied Properties and it's merely a shortcut for getter-only properties:
private string m
{
get { return string.Empty; }
}
As for the benefits of this approach, I guess you can treat it as syntactic sugar that is only saving you some keystrokes.
See Roslyn Wiki
It's not a variable, it's an expression bodied property. A read-only property, in your case returning string.Empty.
It's the same as
private string m { get { return string.Empty; } }
It's one of the new features introduced in C# 6.0. The benefit is shorter, more concise code. Especially if you have a class with a lot of simple read-only properties.
If you want to see a real-world example of this syntax, check the this post on Eric Lippert's blog. As you can see, there's a lot of one-line methods and properties there. Without expression-bodied properties and members, the code would be much longer. And a considerable part of it would be curly braces.
This is not actually a variable initialization, this binds the lambda expression "string.Empty" to "m", so whenever you dereference "m", it will actually evaluate your lambda expression.
For further reading check out this github page (section "Expression-bodied function member")

C# - Is it possible to get the owner type of a method from an Action?

I have a class that implements an Interface with some methods.
I also have method with an Action parameter where I pass the Interface method.
Is it possible to get the type of the owner that has the method?
EDIT
This is the wrapper:
private void Wrapper (params Action[] actions)
{
var action = actions.FirstOrDefault();
var type = action.Method.DeclaringType.Name;
}
private void test()
{
Wrapper(()=> _GC.ChargeCancellation(""));
}
For demonstration purpose I don't iterate through the collection.
I want the type of _GC.
Actually, I should've spotted this to begin with but since Jon didn't either I'm not feeling too bad about it :)
The code you have to begin with in your question does not compile:
Wrapper(() => TestClass.Hello);
This is not complete code. You either have to have:
Wrapper(TestClass.Hello);
^
|
+-- notice the missing () => here
or:
Wrapper(() => TestClass.Hello());
^
|
+-- notice the added parenthesis here
And now that you have edited your question, it is clear you have the second form.
There's a subtle difference between the two. Subtle to us, but important to the compiler:
Wrapper(TestClass.Hello);
^------+------^
|
+-- This is a method group
Wrapper(() => TestClass.Hello());
^------+--------^
|
+-- This is a method call
A method group is a reference to a method (or its overloads), a method call is executable code.
The difference to the compiler is that in the first piece of code, the compiler will wrap up the method group into an action, basically compile it like this:
Wrapper(new Action(TestClass.Hello));
and thus, you're passing that method to the Wrapper method, inside an Action delegate.
However, the second form is handled altogether differently. The compiler now produces a new method to contain your code, and then passes the new method to the Wrapper method instead of the code you had.
Thus, your code actually looks like this:
public static void Main()
{
Wrapper(new Action(TempMethod1));
}
private static void TempMethod1()
{
TestClass.Hello();
}
And that's why you're seeing the form class as the owner of the method, because that's what it is.
The reason I asked in a comment whether you were taking a delegate or an expression is that my brain was working at half speed. It detected something odd, but not the whole picture.
If you want to pass code like this to a method, and work with it, you have two choices:
For a delegate, work with reflection, decompile the code and analyze it, find the method call and figure out which class it is made on
For an expression, analyze the pieces of the expression (this requires C# 3 or above)
Since neither is trivial I'm not going to post any code here, suffice to say that what you're asking warrants a new question. Of the two, I suggest you go with the expression way if you can.
EDIT: I misread the example, and thought it was using a method group conversion. You can certainly get the method in the delegate itself:
public void Wrapper(Action action)
{
MethodInfo method = action.Method;
Type type = method.DeclaringType; // TestClass
string name = method.Name; // Hello
}
I'm not sure off the top of my head which method will be used if you pass in a delegate instance with multiple actions... but it shouldn't be a problem in this case.
Doh - I misread the question. When you use a lambda expression, that's going to build an extra method in the calling class - and that is the method which contains the reference to _GC.
If you don't want this behaviour, you should change Wrapper to accept params Expression<Action>[] actions - you can then examine the expression trees appropriately and find out the calls that way. It's a bit fiddly sometimes, but it's doable. Look at the Body of the expression tree, which will represent the method call. Note that if you still want to execute the actions, you can call Compile on the expression tree to obtain a delegate.

What is '=>'? (C# Grammar Question) [duplicate]

This question already has answers here:
What does the '=>' syntax in C# mean?
(7 answers)
Closed 8 years ago.
I was watching a Silverlight tutorial video, and I came across an unfamiliar expression
in the example code.
what is => ?
what is its name? could you please provide me a link?
I couldn't search for it because they are special characters.
code:
var ctx = new EventManagerDomainContext();
ctx.Events.Add(newEvent);
ctx.SubmitChanges((op) =>
{
if (!op.HasError)
{
NavigateToEditEvent(newEvent.EventID);
}
}, null);
It's a lambda expression.
If you're familiar with anonymous methods from C# 2, lambda expressions are mostly similar but more concise. So the code you've got could be written like this with an anonymous method:
var ctx = new EventManagerDomainContext();
ctx.Events.Add(newEvent);
ctx.SubmitChanges(delegate(Operation op)
{
if (!op.HasError)
{
NavigateToEditEvent(newEvent.EventID);
}
}, null);
Aspects of anonymous methods such as the behaviour of captured variables work the same way for lambda expressions. Lambda expressions and anonymous methods are collectively called anonymous functions.
There are a few differences, however:
Lambda expressions can be converted into expression trees as well as delegates.
Lambda expressions have a number of shortcuts to make them more concise:
If the compiler can infer the parameter types, you don't need to specify them
If the body is a single statement, you don't need to put it in braces and you can omit the "return" part of a return statement
If you have a single parameter with an inferred type, you can miss out the brackets
Putting these together, you get things like:
IEnumerable<string> names = people.Select(person => person.Name);
Lambda expressions don't support the "I don't care how many parameters there are" form of anonymous methods, e.g.
EventHandler x = delegate { Console.WriteLine("I was called"); };
Lambda operator:
A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls...
Huzzah!
I couldn't search for it because they are special characters.
Sometimes the old-fashioned ways are the best. This worked for me:
Start Visual Studio 2008 or later
Hit F1
Once the Help Document Explorer has come up, ensure the Index tab is selected in the left hand pane
Enter => in the Look for field
The first item in the list is now the help article you need.

C# Delegate Instantiation vs. Just Passing the Method Reference [duplicate]

This question already has answers here:
Difference between wiring events with and without "new"
(6 answers)
What is the difference between Events with Delegate Handlers and those without? [duplicate]
(4 answers)
Closed 1 year ago.
I have a simple question: what's the advantage of instantiating a C# delegate as opposed to just passing the function reference? What I mean is:
Why do:
Thread t = new Thread(new ThreadStart(SomeObject.SomeMethod));
When you can do:
Thread t = new Thread(SomeObject.SomeMethod);
Both will compile and work in my experience...am I missing something?
As long as the method group SomeObject.SomeMethod has a method with return type void and taking no parameters there is no difference. This is because ThreadStart is defined as a delegate that returns void and takes no parameters and therefore there is an implicit conversion from the method group SomeObject.SomeMethod to ThreadStart. Thus, both are invoking the overload Thread(ThreadStart) of the Thread constructor .
The relevant section of the language specification is §6.6 (Method group conversions).
I have a simple question: what's the advantage of instantiating a C# delegate as opposed to just passing the function reference?
So, just a correction of terminology here. With
class MyObject {
public void SomeMethod() { }
}
MyObject someObject = new MyObject();
the thing denoted by someObject.SomeMethod is a method group. You can just think of it as the set of overloaded methods can that be looked up using the notation someObject.SomeMethod.
The compiler will infer that when you typed the shorter code, you meant the longer code. There's no difference in the ultimate effect. If you want the clarity of the full constructor, you can put it in; if you want the brevity of just the method group, you can allow the compiler to infer the constructor. It's just a stylistic choice.
That's equivalent. Good introductory article on the subject: C# Delegates, Anonymous Methods, and Lambda Expressions – O My!

Can I ignore delegate parameters with lambda syntax?

I am curious why C# allows me to ignore delegate parameters in some cases but not others.
For instance this is permitted:
Action<int> action = delegate { Console.WriteLine("delegate"); };
but this is not:
Action<int> action = () => Console.WriteLine("lambda");
Is there a way to initialize a delegate and ignore the parameters using a lambda? I know that I can add a single parameter to the lambda and fix the previous line but this is more of an academic question pertaining to the compiler and why or how this works.
I believe that your first sample actually creates an anonymous function that is able to take on many different signatures whose body is the single statement Console.WriteLine.... Because it can match different signatures, it does not cause a problem. In the second sample, the lambda syntax itself defines a function that takes no parameters with the same body. Obviously the latter is not consistent with the defined Action so you get the error.
C# Anonymous Method Reference
There is one case in which an
anonymous method provides
functionality not found in lambda
expressions. Anonymous methods enable
you to omit the parameter list, and
this means that an anonymous method
can be converted to delegates with a
variety of signatures. This is not
possible with lambda expressions.
To elaborate on tvanfosson's answer; this behavior is described in the C# 3.0 language specification (§7.14):
The behavior of lambda-expressions and
anonymous-method-expressions is the
same except for the following points:
• anonymous-method-expressions permit
the parameter list to be omitted
entirely, yielding convertibility to
delegate types of any list of value
parameters.
• lambda-expressions permit parameter
types to be omitted and inferred
whereas anonymous-method-expressions
require parameter types to be
explicitly stated.
• The body of a lambda-expression can
be an expression or a statement block
whereas the body of an
anonymous-method-expression must be a
statement block.
• Since only lambda-expressions can
have an expression body, no
anonymous-method-expression can be
successfully converted to an
expression tree type (§4.6).
I think:
Action<int> action = () => Console.WriteLine("lambda");
is the equivalent of:
Action<int> action = delegate() { Console.WriteLine("delegate"); };
which wouldn't compile either. As Daniel Plaisted says () is explicitly saying there aren't any parameters.
If there were an equivalent of delegate{} it might be:
Action<int> action = => Console.WriteLine("lambda")
Which isn't very pretty and I suspect it suspect isn't in the spirit of lambda expressions.
As others said, no, you can't skip declaring the parameters to a lambda. But, for cleanliness, I suggest giving them a name such as _. For example
foo.Click += (_,__) => { ... }
You aren't ignoring them per-se, but you're indicating you don't care what they are and will not use them.
The () => ... syntax explicitly specifies that the lambda takes no parameters. Perhaps the language could be modified so that () => really meant "Infer the parameters of this lambda for me" in the same way the delegate syntax does, but that would make the language more complicated. When designing new language features, you start at minus 100, and I don't think this one passes the test.
There may also be more technical reasons why this would be difficult to implement (which is probably more in line with what you were asking for, but I doubt the technical reasons drove this decision if it ever came up).
I'd say it's to have a forced use of the parameters of the lambda expression.
Take your first example, how would you interact with the passed in value, there's no local representation of it.
What about this?
Func<int> lamdapointer = () => TwoArgMethodThatReturnsInt(10,20); // the same method cannot be called with the delegate "NoArgmethodThatReturnsInt"
lamdapointer();
Delegate int NoArgmethodThatReturnsInt();
NoArgmethodThatReturnsInt del = NoArgmethodThatReturnsInt; // only this is possible with delegates
public int TwoArgMethodThatReturnsInt(int x,int y)
{
return x + y;
}
public int NoArgmethodThatReturnsInt()
{
return 20;
}
Actually, delegate {} does not specify any parameters and fits any delegate method signature - therefore it is permitted in your first construcion.
The Lambda expression () => ...; specifically states parameterless delegate, which contradicts the signature required by Action - a delegate with single parameter.
You may want to use one of the following options.
If you need the action to have a parameter, you can do it the next way ("_" is a legal character for identifier name).
Action<int> action = _ => Console.WriteLine("lambda");
Or you may want to use parameterless Action as follows:
Action action = () => Console.WriteLine("lambda");

Categories

Resources