I was reading about Web API 2 and Entity Framework where I bumped across this line:
this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
I looked up the => operator and found that it has something to do with lambdas, although I'm still not sure exactly how it fits in or what's going on here. Can anybody help me out? What's going on in this line?
this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
Basically means:
this.Database.Log = blah;
void blah(string s)
{
System.Diagnostics.Debug.WriteLine(s);
}
Database.Log is of the type Action<T>, which is a delegate type
See the property on MSDN
See Action<T> on MSDN
See delegates on MSDN
See lamdas on MSDN
So when this.Database wants to log stuff, it'll call it's "Log" property which is an Action<string>. Since it's an Action<string> (and more importantly, Action<T> is a delegate type), you can assign either a method which returns no value and has a single parameter (which is a string) or a lamda with a single parameter (also, string) (and no return value).
The Database.Log property is of type Action<string>. That means it's a delegate that takes a string and has no return value (i.e. its return type is void). So this line assigns the to the Log property an anonymous function which accepts a string value and writes it to the debugger window.
Because you're assigning the lambda expression to a property with a known delegate type, the compiler can infer the type of the argument (s) and return type from the context. This is shorthand for
this.Database.Log = (delegate (string s){ System.Diagnostics.Debug.WriteLine(s); });
Which in turn is short hand for (as the other answers mention) creating a private method and assigning a delegate reference to that private method:
this.Database.Log = (Action<string>)__compiler_generated_function__;
private void __compiler_generated_function__(string s) {
System.Diagnostics.Debug.WriteLine(s);
}
It means assign a function to this.Database.Log. When this.Database.Log executes it finds the function
s => System.Diagnostics.Debug.WriteLine(s);
That stands for
void LogMethod(string s)
{
System.Diagnostics.Debug.WriteLine(s);
}
Related
I have the following code:
Func<string, string> func1 = (param) =>
{
Console.WriteLine("Func 1 executing");
return "Hello" + param;
};
Func<string, string> func2 = (param) =>
{
Console.WriteLine("Func 2 executing");
return "World" + param;
};
Func<string, string> funcSum = func1 + func2;
string funcResult = funcSum("!");
Console.WriteLine(funcResult);
The output is:
Func 1 executing
Func 2 executing
World!
Inverting the sum:
Func<string, string> funcSum = func2 + func1;
Gives the output:
Func 2 executing
Func 1 executing
Hello!
My initial test was done with a boolean return type, and the returned value was also always determined by the last function. Is it working as intended? Aren't we losing the return value of the other functions? If so, is there a use case in real world of those multicast delegate of functions?
Is it working as intended?
It's working as specified, at least. Whether that's what you intended or not is a different matter :) From section 15.4 of the C# 5 specification - emphasis mine:
Invocation of a delegate instance whose invocation list contains multiple entries proceeds by invoking each of the methods in the invocation list, synchronously, in order. Each method so called is passed the same set of arguments as was given to the delegate instance. If such a delegate invocation includes reference parameters (§10.6.1.2), each method invocation will occur with a reference to the same variable; changes to that variable by one method in the invocation list will be visible to methods further down the invocation list. If the delegate invocation includes output parameters or a return value, their final value will come from the invocation of the last delegate in the list.
Next:
Aren't we losing the return value of the other functions?
Yes, at the moment.
If so, is there a use case in real world of those multicast delegate of functions?
Very rarely, to be honest. However, you can split a multicast delegate apart, using Delegate.GetInvocationList():
foreach (Func<string, string> func in funcSum.GetInvocationList())
{
Console.WriteLine(func("!"));
}
Most of your question has been answered already, but one thing that's missing is a real-world use case for this. Here's one: asynchronous event handlers.
public delegate Task AsyncEventHandler(object sender, EventArgs e);
public event AsyncEventHandler X;
public async Task OnX(EventArgs e) {
// ...
var #event = X;
if (#event != null)
await Task.WhenAll(
Array.ConvertAll(
#event.GetInvocationList(),
d => ((AsyncEventHandler)d)(this, e)));
}
This allows the user of the class to simply write
myobject.X += async (sender, e) => { ... };
but the object will still ensure that OnX's task doesn't complete until the event handler's has.
The multicast delegate will always return the result of the last function. Because there is no predefined way to combine or chain the T results.
If you want to obtain all the results along the chain, try this :
var result = "!";
foreach (Func<string, string> func in funcSum.GetInvocationList())
{
result = func(result);
}
I have the following code:
Func<string, string> func1 = (param) =>
{
Console.WriteLine("Func 1 executing");
return "Hello" + param;
};
Func<string, string> func2 = (param) =>
{
Console.WriteLine("Func 2 executing");
return "World" + param;
};
Func<string, string> funcSum = func1 + func2;
string funcResult = funcSum("!");
Console.WriteLine(funcResult);
The output is:
Func 1 executing
Func 2 executing
World!
Inverting the sum:
Func<string, string> funcSum = func2 + func1;
Gives the output:
Func 2 executing
Func 1 executing
Hello!
My initial test was done with a boolean return type, and the returned value was also always determined by the last function. Is it working as intended? Aren't we losing the return value of the other functions? If so, is there a use case in real world of those multicast delegate of functions?
Is it working as intended?
It's working as specified, at least. Whether that's what you intended or not is a different matter :) From section 15.4 of the C# 5 specification - emphasis mine:
Invocation of a delegate instance whose invocation list contains multiple entries proceeds by invoking each of the methods in the invocation list, synchronously, in order. Each method so called is passed the same set of arguments as was given to the delegate instance. If such a delegate invocation includes reference parameters (§10.6.1.2), each method invocation will occur with a reference to the same variable; changes to that variable by one method in the invocation list will be visible to methods further down the invocation list. If the delegate invocation includes output parameters or a return value, their final value will come from the invocation of the last delegate in the list.
Next:
Aren't we losing the return value of the other functions?
Yes, at the moment.
If so, is there a use case in real world of those multicast delegate of functions?
Very rarely, to be honest. However, you can split a multicast delegate apart, using Delegate.GetInvocationList():
foreach (Func<string, string> func in funcSum.GetInvocationList())
{
Console.WriteLine(func("!"));
}
Most of your question has been answered already, but one thing that's missing is a real-world use case for this. Here's one: asynchronous event handlers.
public delegate Task AsyncEventHandler(object sender, EventArgs e);
public event AsyncEventHandler X;
public async Task OnX(EventArgs e) {
// ...
var #event = X;
if (#event != null)
await Task.WhenAll(
Array.ConvertAll(
#event.GetInvocationList(),
d => ((AsyncEventHandler)d)(this, e)));
}
This allows the user of the class to simply write
myobject.X += async (sender, e) => { ... };
but the object will still ensure that OnX's task doesn't complete until the event handler's has.
The multicast delegate will always return the result of the last function. Because there is no predefined way to combine or chain the T results.
If you want to obtain all the results along the chain, try this :
var result = "!";
foreach (Func<string, string> func in funcSum.GetInvocationList())
{
result = func(result);
}
I'm working on a method that needs to repeat a small operation at different spots, but the code to be repeated should be private to the method. The obvious solution is a nested function. Whatever I try however, the C# compiler barfs at me.
Something roughly equal to this Perl snippet:
my $method = sub {
$helper_func = sub { code to encapsulate };
# more code
&$helper( called whenever needed );
# more code
}
is what I am talking about, and what I'm trying to accomplish in C#.
No other method in the class should be able to access the helper function in this context. The most logical means of writing this construct in C#, as it appears to me would be something like this:
var helper = (/* parameter names */) => { /* code to encapsulate */ };
And actually make the compiler earn its keep.
Since such an assignment is forbidden, as is the equivalent using the older delegate(){} syntax in place of the lambda, and so is declaring a delegate type within a method—what csc actually allows me to write however, is this:
private delegate /* return type */ Helper(/* parameters */);
private /* return type */ method(/* parameters */) {
Helper helper = (/* parameter names */) => {
/* code to encapsulate */
};
// more code
helper( /* called whenever needed */ );
// more code
}
Which is all fine and dandy for not copy and pasting a chunk of code around and editing the parameters by hand but it leaks a private delegate type to the rest of the class rather than keeping it private to the method. Which defeats the purpose in the first place. Using goto statements and local variables for parameters would provide better encapsulation of "helper" in this context without sacrificing code reuse. If I wanted to simulate function calls by passing parameters through registers, I think would rather use an assembler. I haven't found an acceptable way of refactoring the code to avoid the problem altogether either.
So, is it even possible to force this Common Object Oriented Language to obey?
You actually can do this in C#.
Func<T1, T2, ..., TReturn> myFunc = (a, b, ...) =>
{
//code that return type TReturn
};
If you need an anonymous method of return type void use Action instead of Func:
Action<T1, T2, ...> myAction = (a, b, ...) =>
{
//code that doesn't return anything
};
If you are in C# 3.5 or higher you can take advantage of the lambdas and convenience delegate declarations Func<> and Action<>. So for instance
void DoSomething()
{
Func<int,int> addOne = (ii) => ii +1;
var two = addOne(1);
}
The reason you can't do
var addOne = (ii) => ii +1;
is because of Homoiconicity, the lambda can be interpreted as two different constructs, a delegate and an expression tree. Thus the need to be explicit in declaration.
If you explicitly type it, it will work, i.e.
Action<paramType1, paramType2> helperAction = (/* parameter names */) => { /* code to encapsulate */ };
Func<paramType1, paramType2, returnType> helperFunction = (/* parameter names */) => { /* code to encapsulate */ };
The reason var doesn't work is that a lambda expression can evaluate to multiple types (I believe either a delegate or expression tree, but don't quote me on that) and the compiler in this situation is unable to infer which was meant.
I recommend looking at the Action<T> and Func<TResult> delegates and their overloads. You can do something like this
static void Main(string[] args)
{
SomeMethod();
}
private static void SomeMethod()
{
Action<int> action = (num) => Console.WriteLine(num);
Enumerable.Range(1,10).ToList().ForEach(action);
Console.ReadKey();
}
Here SomeMethod is private and has a local Action<int> delgate that takes an int and does something to it.
I think the issue that you came across is that you can't use implicit typing (i.e. use var) when assigning a lambda expression to a variable.
You can't use the var keyword with lambdas or delegates because they both require additional context information (delegates require a return type, and lambdas require a return type and parameter types). For instance, the (params) => { code } syntax requires to be able to infer the parameter types and return types to work: you do this by explicitly giving it a type.
The generic System.Action delegate type (returns void) could do a good job at what you're trying:
Action<ArgumentType1, ArgumentType2, ...> myDelegate = (params) => { code };
Otherwise, there's also the System.Func, which has a return type, that must be passed as the last generic argument.
It depends on what your definition of hiding is.
The func/action solution (like the one Scott suggests)
void DoSomething()
{
Func<int,int> addOne = (ii) => ii +1;
var two = addOne(1);
}
Feals like hidding the method definition when writing regular C# code BUT is when looking at the IL equivalent of
//This is pseudo code but comes close at the important parts
public class Class1
{
//The actual type is different from this
private static Func<int, int> myMethod = AnonymousFunction;
public void f()
{
myMethod(0);
}
private static int AnonymousFunction(int i)
{
return 1;
}
}
So if you really want to get to the method from outside of the one "hidding" it you can do this with reflection The actual name generated for the field storing the delegate is illegal in C# bul valid in CLR context but that's the only thing that stand in the way of using the delegate as a regular delegate stored in a field (that is if you figue out the name :) )
It's quite simple actually. As the Method seems to have another responsibility than your current Class (why else would you hide this method) move your method into it's own Class and the part you want to have private into a private method in the new class.
Completly new here with a question regaridng this post : ThreadPool.QueueUserWorkItem with a lambda expression and anonymous method
Specific this :
ThreadPool.QueueUserWorkItem(
o => test.DoWork(s1, s2)
);
Can somebody please explain what the 'o' is? I can see the (in VS2008) that it is a object parameter but I basically don't understand why and how.
ThreadPool.QueueUserWorkItem requires a WaitCallback delegate as argument.
This delegate type corresponds to void function of one argument of type Object.
So, full version of the call could be
ThreadPool.QueueUserWorkItem(
new WaitCallback(delegate(object state) { test.DoWork(s1,s2); });
);
More concise would be
ThreadPool.QueueUserWorkItem(
delegate(object state) { test.DoWork(s1,s2); };
);
Using C# 3.0 syntax we can write it in more short form:
ThreadPool.QueueUserWorkItem(
(object state) => { test.DoWork(s1,s2); };
);
C# 3.0 lambda syntax allows to omit state's type. As this argument isn't really needed, it is also abbreviated to the first letter of its type.
From the documentation of QueueUserWorkItem, the first parameter is a WaitCallback with the following definition:
public delegate void WaitCallback(
Object state
)
The definition of state is:
Type: System.Object
An object containing information to be used by the callback method.
So the first parameter of QueueUserWorkItem is a function which takes an object (an optional user state) and does something that returns void. In your code, o is the user state object. It is not used in this case, but it has to be there.
Just look it up: The o is a state object you may pass to the executed method using the overloaded version of QueueUserWorkItem. When you don't pass one explicitly, it's null.
This way useful in times when no lambda expression were available.
o is a formal parameter to the lambda function. Its type is derived by the parameter type of QueueUserWorkItem.
The other answers are good, but maybe it helps if you see what is the equivalent without using neither lambda expressions nor delegate methods (that is, doing it the .NET 1 way):
void SomeMethod()
{
//...
ThreadPool.QueueUserWorkItem(new WaitCallback(TheCallback));
//...
}
void TheCallback(object o)
{
test.DoWork(s1, s2);
}
I have a function that wraps a call to one of my socket types. If there is an error, I want to be able to print a warning and retry. In the warning, I want to have the method name. However, it was declared as a lambda. Is this even possible?
How I call the function (assume in function called myMain):
SafeSocketCommand(() => this.mySocket.ReadCurrentBuffer());
Basic wrapping function:
protected TResult SafeSocketCommand<TResult>(Func<TResult> socketCommand)
{
TResult retValue = default(TResult);
try
{
retValue = socketCommand();
}
catch (PacketLost)
{
ReportToLogs("Timeout on command '" + socketCommand.Method.Name);
}
return retValue;
}
But socketCommand.Method.Name gives me the calling method (from the Stack Trace?) '< myMain >b__3' and I want the actual function being invoked by socketCommand (mySocket.ReadCurrentBuffer). Is it possible to get this information anywhere, or is it lost due to declaring in a lambda?
EDIT:
I should have mentioned that I use this particular calling convention so that I can use socket based commands of various signatures.
int i = SafeSocketCommand(() => this.mySocket.FunctionReturnsInt())
bool b = SafeSocketCommand(() => this.mySocket.FunctionReturnsBool(string s))
object o = SafeSocketCommand(() => this.mySocket.Complicated(string s, int i, bool b))
It also handles no return type signatures by overloading:
protected void SafeSocketCommand(Action socketCommand)
{
SafeSocketCommand(() => { socketCommand(); return 0; });
}
If you modify your SafeSocketCommand to accept an Expression<Func<TResult>> then you'll get access to an expression tree that represents the body of the lambda, from which you can access the ReadCurrentBuffer call directly.
However, if you do this, you're no longer dealing with a regular anonymous method; to actually call it you'll need to compile the expression tree to code. You may also need to be flexible as to what your code expects to appear inside the lambda's body.
No, because lambda's don't have names; they're anonymous functions. You could get the method name from the last stackframe, though:
new StackFrame(1).GetMethod().Name;
Func<TResult> is just a delegate. Rather than use a lambda, create a method that matches the signature of Func<TResult> and call that. That way, you'll have whatever name you want.
SafeSocketCommand(MyNewMethod);
...
public TResult MyNewMethod()
{
return this.mySocket.ReadCurrentBuffer();
}
In this case, you can simply this call instead. It'll be faster and smaller generated code too.
SafeSocketCommand(mySocket.ReadCurrentBuffer);
In general, the StackTrace of the Exception object contains the full information you are looking for, much more accurately than printing the method name, or you can use the TargetSite property for the name of the method that threw the exception.