The difference between += and Delegate.Combine - c#

I've built an event system that maintains a dictionary of delegates, adds/removes elements to this dictionary via generic Subscribe/Unsubscribe methods (which each take an Action of type T), and has a Publish method to notify the subscribers when something happens (which also takes an Action of type T). Everything works fine, but I've noticed I cannot use += or -= when adding or removing elements to my dictionary, as the types passed into the methods (Action of T), do not match the types stored in the dictionary (Delegate). The following snippet shows what I can and cannot do.
private readonly Dictionary<Type, Delegate> delegates = new Dictionary<Type, Delegate>();
public void Subscribe<T>(Action<T> del)
{
if (delegates.ContainsKey(typeof(T)))
{
// This doesn't work!
delegates[typeof(T)] += del as Delegate;
// This doesn't work!
delegates[typeof(T)] += del;
// This is ok
delegates[typeof(T)] = (Action<T>)delegates[typeof(T)] + del;
// This is ok
var newDel = (Action<T>)delegates[typeof(T)] + del;
delegates[typeof(T)] = newDel;
// This is ok
del += (Action<T>)delegates[typeof(T)];
delegates[typeof(T)] = del;
// This is ok
delegates[typeof(T)] = Delegate.Combine(delegates[typeof(T)], del);
}
else
{
delegates[typeof(T)] = del;
}
}
I mostly understand Jon Skeet's answer here += operator for Delegate specifically, this part
The binary + operator performs delegate combination when both operands are of some delegate type D. (If the operands have different delegate types, a binding-time error occurs.)
What I don't understand, is this
The compiler turns it into a call to Delegate.Combine. The reverse operation, using - or -=, uses Delegate.Remove.
What exactly is going on when I use += or -=, versus Delegate.Combine? What are the differences between the two, making one implementation valid, and another invalid?

At the end of the answer you linked, it says:
Since System.Delegate is not a delegate type, operator + is not defined for it.
This explains why this does not work (both operands are Delegate):
delegates[typeof(T)] += del as Delegate;
Delegate.Combine works because it is declared like this:
public static Delegate Combine (params Delegate[] delegates);
Note how it accepts parameters of type Delegate, instead of a specific delegate type. And it will throw an ArgumentException if the delegates are not of the same type.
So the compiler not only changes the + operator to Delegate.Combine, it also does some type checking! On the other hand, no compile-time type checking is done if you use Delegate.Combine directly. Delegate.Combine only checks the types at runtime.
All the other lines work because you are casting i.e. telling the compiler what type the delegates are, making both operands of + to be of type Action<T>.

Related

How EXACTLY can += and -= operators be interpreted?

What exactly (under the hood) do the += and -= operators do?
Or are they implicit in that they are defined per type?
I've used them extensively, it's a very simple feature of the syntax, but I've never thought about the depths of how it works.
What Brought About the Question
I can concatenate a string value like so:
var myString = "hello ";
myString += "world";
All fine. But why doesn't this work with collections?
var myCol = new List<string>();
myCol += "hi";
You may say 'well you're attempting to append a different type, you can't append a string to a type that isn't string'. But the following doesn't work either:
var myCol = new List<string>();
myCol += new List<string>() { "hi" };
Ok, maybe it doesn't work with collections, but is the following not a (kind of) collection of event handlers?
myButton.Click += myButton_Click;
I'm obviously lacking an in-depth understanding of how these operators work.
Please note: I'm not trying to build the collection myCol in this way, in a real project. I'm merely curious about the workings of this operator, it's hypothetical.
The += operator is implicitly defined like this: a += b turns into a = a + b;, same with the -= operator.
(caveat: as Jeppe pointed out, if a is an expression, it is only evaluated once if you use a+=b, but twice with a=a+b)
You cannot overload the += and -= operator separately. Any type that supports the + operator also supports +=. You can add support for += and -=to your own types by overloading + and -.
There is however one exception hard coded into c#, which you have discovered:
Events have a += and -= operator, which adds and removes an event handler to the list of subscribed event handlers. Despite this, they do not support the + and - operators.
This is not something you can do for your own classes with regular operator overloading.
As the other answer say, the + operator is not defined for List<>. You can check it trying to overload it, the compiler would throw this error One of the parameters of a binary operator must be the containing type.
But as an experiment, you can define your own class inheriting List<string> and define the + operator. Something like this:
class StringList : List<string>
{
public static StringList operator +(StringList lhs, StringList rhs)
{
lhs.AddRange(rhs.ToArray<string>());
return lhs;
}
}
Then you can do this without problems:
StringList listString = new StringList() { "a", "b", "c" };
StringList listString2 = new StringList() { "d", "e", "f" };
listString += listString2;
Edit
Per #EugeneRyabtsev comment, my implementation of the + operator would lead to an unexpected behavior. So it should be more something like this:
public static StringList operator +(StringList lhs, StringList rhs)
{
StringList newList=new StringList();
newList.AddRange(lhs.ToArray<string>());
newList.AddRange(rhs.ToArray<string>());
return newList;
}
The short answer is that operators in C# have to be overloaded for a given type. This also holds for +=. string contains an overload of this operator, but List<> has not. Therefore, using the += operator for lists is not possible. For delegates, the += operator is also overloaded, which is why you can use += on event handlers.
The slightly longer answer is that you are free to overload the operator yourself. However, you have to overload it for your own types, so creating an overload for List<T> is not possible, while you in fact can do this for your own class that for instance inherits from List<T>.
Technically, you do not really overload the +=-operator, but the + operator. The += operator is then inferred by combining the + operator with an assignment. For this to work, the + operator should be overloaded in such a way that the result type matches the type of the first argument, otherwise the C#-compiler is going to throw an error message when you try to use +=.
The correct implementation is actually quite a bit more complex than one would think. First of all, it is not sufficient to say that a += b is exactly the same as a = a+b. It has the same semantics in the simplest of cases, but it is not a simple text substitution.
First, if the expression on the left is more complex than a simple variable, it is only evaluated once. So M().a += b is not the same as M().a = M().a + b, as that would be assigning the value on a completely different object than it was taken from, or would cause the method's side effects to happen twice.
If M() returns a reference type, the compound assignment operator can be thought of as var obj = M(); obj.a = obj.a+b; (but still being an expression). However, if obj was of a value type, this simplification would also not work, in case the method returned a reference (new in C# 7) or if it actually was an array element, or something returned from an indexer etc., then the operator ensures that it doesn't make more copies than needed to modify the object, and it will be applied to a correct place, with no additional side effects.
Event assignment is an entirely different beast, though. Outside the class scope, += results in calling the add accessor, and -= results in calling the remove accessor of the event. If these accessors aren't user-implemented, event assignment might result in calling Delegate.Combine and Delegate.Remove on the internal delegate object inside the class scope. That's also why you cannot simply get the event object outside the class, because it is not public. +=/-= is also not an expression in this case.
I recommend reading Compound Assignment by Eric Lippert. It describes this in much more detail.

Overload resolution on operator == with variant generic delegate types

What are the precise rules for overload resolution with == between two expressions of delegate type?
Consider the following code (where using System; is needed):
static class ProgramA
{
static void TargetMethod(object obj)
{
}
static void Main()
{
Action<object> instance1 = TargetMethod;
Action<object> instance2 = TargetMethod;
Action<string> a1 = instance1;
Action<Uri> a2 = instance2;
Console.WriteLine((object)a1 == (object)a2);
Console.WriteLine((Delegate)a1 == (Delegate)a2);
Console.WriteLine((Action<object>)a1 == (Action<object>)a2);
Console.WriteLine(a1 == a2); // warning CS0253: Possible unintended reference comparison; to get a value comparison, cast the right hand side to type 'System.Action<string>'
}
}
Explanation:
instance1 and instance2 are two separate instances of the same run-time type, the generic Action<in T> which is contravariant in T. Those instances are distinct but Equals since they the have same targets.
a1 and a2 are the same as instance1 and instance2, but because of the contravariance of Action<in T> there exist implicit reference conversions from Action<object> to each of Action<string> and Action<System.Uri>.
Now, the C# Language Specification has (among other overloads) these operator ==:
bool operator ==(object x, object y); // §7.10.6
bool operator ==(System.Delegate x, System.Delegate y); // §7.10.8
The current Visual C# compiler realizes the first one by simply checking if the references are the same (the IL does not actually call a mscorlib method like object.ReferenceEquals, but that would give the same result), while it realizes the second one by calling Delegate.op_Equality method which looks like a "user-defined" operator inside that assembly even when it is defined by the C# Language Spec, so is maybe not "user-defined" in the sense of the spec(?).
Note that §7.10.8 is a little confusing because it says "Every delegate type implicitly provides the following predefined comparison operator[s]" and then gives the operator with the (System.Delegate, System.Delegate) signature. That is just one operator, not one for "every" delegate type? This seems important for my question.
It is not surprising that the three first WriteLine write False, True and True, respectively, given what I said above.
Question: But why does the fourth WriteLine lead to the (object, object) overload being used?
There does exist an implicit reference conversion from Action<> (or any other delegate type) to System.Delegate, so why can't that be used here? Overload resolution should prefer that over the (object, object) option.
Of course, there are no implicit conversions between Action<string> and Action<Uri>, but why is that relevant? If I create my own class MyBaseClass containing a user-defined operator ==(MyBaseClass x, MyBaseClass y) and I create two unrelated deriving classes, then my == operator will still be used (left and right operand not convertible to each other but both convertible to MyBaseClass).
Just for completeness, here is the analogous example with covariance (Func<out TResult>) instead of contravariance:
static class ProgramF
{
static string TargetMethod()
{
return "dummy";
}
static void Main()
{
Func<string> instance1 = TargetMethod;
Func<string> instance2 = TargetMethod;
Func<ICloneable> f1 = instance1;
Func<IConvertible> f2 = instance2;
Console.WriteLine((object)f1 == (object)f2);
Console.WriteLine((Delegate)f1 == (Delegate)f2);
Console.WriteLine((Func<string>)f1 == (Func<string>)f2);
Console.WriteLine(f1 == f2); // warning CS0253: Possible unintended reference comparison; to get a value comparison, cast the right hand side to type 'System.Func<System.ICloneable>'
}
}
A question related to my question above is, where in the C# Language Specification does it say that this shall be illegal:
Func<string> g1 = ...;
Func<Uri> g2 = ...;
Console.WriteLine(g1 == g2); // error CS0019: Operator '==' cannot be applied to operands of type 'System.Func<string>' and 'System.Func<System.Uri>'
I can see that the compiler figured out that no type can ever inherit from both string and Uri (unlike the pair ICloneable and IConvertible), and so this (if it were legal) could only become true if both variables were null, but where does it say that I am not allowed to do this? In this case it would not matter if the compiler chose operator ==(object, object) or operator ==(Delegate, Delegate) since, as I said, it comes down to checking if both are null references, and both overloads do that in the same way.
Question: But why does the fourth WriteLine lead to the (object, object) overload being used?
Because it's the only choice for the compiler :-)
Cannot apply operator '==' to operands of type 'System.Func<System.ICloneable>' and 'System.Func<System.IConvertable>'
candidates are:
bool==(System.Delegate, System.Delegate)
bool==(System.Func<System.ICloneable>, System.Func<System.ICloneable>)
bool==(System.Func<System.IConvertable>, System.Func<System.IConvertable>)
so using your (object, object) is the best choice the compiler finds.
same for the Actions
Cannot apply operator '==' to operands of type 'System.Action<string>' and 'System.Action<System.Uri>'
candidates are:
bool==(System.Delegate, System.Delegate)
bool==(System.Action<string>, System.Action<string>)
bool==(System.Action<System.Uri>, System.Action<System.Uri>)

When is it valid to say a method group conversion has taken place?

So i'm not really convinced when its safe to say that a method group conversion occured.
We have this multicast delegate from a previous post:
public partial class MainPage : PhoneApplicationPage
{
public delegate void MyDelegate(int a, int b);
// Constructor
public MainPage()
{
InitializeComponent();
MyDelegate myDel = new MyDelegate(AddNumbers);
myDel += new MyDelegate(MultiplyNumbers);
myDel(10, 20);
}
public void AddNumbers(int x, int y)
{
int sum = x + y;
MessageBox.Show(sum.ToString());
}
public void MultiplyNumbers(int x, int y)
{
int mul = x * y;
MessageBox.Show(mul.ToString());
}
}
I say that a method group conversion only occurs when we have assigned a method thats overloaded, and at least one overload matches the delegate. In this case there is no method group conversion.
a fellow programmer says that if you don't think MyDelegate myDel = AddNumbers; (with names referring to the question) is a method group conversion, then what would it be then?
The C# Language Specification: An implicit conversion (§6.1) exists from a method group (§7.1) to a compatible delegate type. Given a delegate type D and an expression E that is classified as a method group, an implicit conversion exists from E to D if [...]
So wich point of view is correct?
I say that a method group conversion only occurs when we have assigned a method thats overloaded
Nope, there's no requirement of overloading (by multiple methods) for method group conversions.
Any time you've got just a method name, or a method name qualified with a target (e.g. MultiplyNumbers or foo.MultiplyNumbers), that's a method group. If you're converting that to a delegate instance, that's a method group conversion.
EDIT: The section of the spec which is causing problems is this, in 7.1:
A method group, which is a set of overloaded methods resulting from a member lookup (7.4).
That "set of overloaded methods" can be a set of size 1 - it's still a method group.
This is backed up by 7.6.5.1 (Method Invocations) - emphasis mine:
For a method invocation, the primary-expression of the invocation-expression must be a method group. The method group identifies the one method to invoke or the set of overloaded methods from which to choose a specific method to invoke.
That makes it clear that a method group with one element is a meaningful concept.
Method group conversion has nothing to do with overloads. Don't get confused by "method group". It doesn't mean that it has to be more than one.
You have assigned a method in which at least one overload matches the delegate - it just so happens there is only one overload. The point of the "conversion" is simply that the compiler can infer the new MyDelegate bit rather than you needing to explicitly construct it.

Why can't an anonymous method be assigned to var?

I have the following code:
Func<string, bool> comparer = delegate(string value) {
return value != "0";
};
However, the following does not compile:
var comparer = delegate(string value) {
return value != "0";
};
Why can't the compiler figure out it is a Func<string, bool>? It takes one string parameter, and returns a boolean. Instead, it gives me the error:
Cannot assign anonymous method to an
implicitly-typed local variable.
I have one guess and that is if the var version compiled, it would lack consistency if I had the following:
var comparer = delegate(string arg1, string arg2, string arg3, string arg4, string arg5) {
return false;
};
The above wouldn't make sense since Func<> allows only up to 4 arguments (in .NET 3.5, which is what I am using). Perhaps someone could clarify the problem. Thanks.
UPDATE: This answer was written over ten years ago and should be considered to be of historical interest; in C# 10 the compiler will infer some delegate types.
Others have already pointed out that there are infinitely many possible delegate types that you could have meant; what is so special about Func that it deserves to be the default instead of Predicate or Action or any other possibility? And, for lambdas, why is it obvious that the intention is to choose the delegate form, rather than the expression tree form?
But we could say that Func is special, and that the inferred type of a lambda or anonymous method is Func of something. We'd still have all kinds of problems. What types would you like to be inferred for the following cases?
var x1 = (ref int y)=>123;
There is no Func<T> type that takes a ref anything.
var x2 = y=>123;
We don't know the type of the formal parameter, though we do know the return. (Or do we? Is the return int? long? short? byte?)
var x3 = (int y)=>null;
We don't know the return type, but it can't be void. The return type could be any reference type or any nullable value type.
var x4 = (int y)=>{ throw new Exception(); }
Again, we don't know the return type, and this time it can be void.
var x5 = (int y)=> q += y;
Is that intended to be a void-returning statement lambda or something that returns the value that was assigned to q? Both are legal; which should we choose?
Now, you might say, well, just don't support any of those features. Just support "normal" cases where the types can be worked out. That doesn't help. How does that make my life easier? If the feature works sometimes and fails sometimes then I still have to write the code to detect all of those failure situations and give a meaningful error message for each. We still have to specify all that behaviour, document it, write tests for it, and so on. This is a very expensive feature that saves the user maybe half a dozen keystrokes. We have better ways to add value to the language than spending a lot of time writing test cases for a feature that doesn't work half the time and doesn't provide hardly any benefit in cases where it does work.
The situation where it is actually useful is:
var xAnon = (int y)=>new { Y = y };
because there is no "speakable" type for that thing. But we have this problem all the time, and we just use method type inference to deduce the type:
Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });
and now method type inference works out what the func type is.
Only Eric Lippert knows for sure, but I think it's because the signature of the delegate type doesn't uniquely determine the type.
Consider your example:
var comparer = delegate(string value) { return value != "0"; };
Here are two possible inferences for what the var should be:
Predicate<string> comparer = delegate(string value) { return value != "0"; }; // okay
Func<string, bool> comparer = delegate(string value) { return value != "0"; }; // also okay
Which one should the compiler infer? There's no good reason to choose one or the other. And although a Predicate<T> is functionally equivalent to a Func<T, bool>, they are still different types at the level of the .NET type system. The compiler therefore cannot unambiguously resolve the delegate type, and must fail the type inference.
Eric Lippert has an old post about it where he says
And in fact the C# 2.0 specification
calls this out. Method group
expressions and anonymous method
expressions are typeless expressions
in C# 2.0, and lambda expressions join
them in C# 3.0. Therefore it is
illegal for them to appear "naked" on
the right hand side of an implicit
declaration.
Different delegates are considered different types. e.g., Action is different than MethodInvoker, and an instance of Action can't be assigned to a variable of type MethodInvoker.
So, given an anonymous delegate (or lambda) like () => {}, is it an Action or a MethodInvoker? The compiler can't tell.
Similarly, if I declare a delegate type taking a string argument and returning a bool, how would the compiler know you really wanted a Func<string, bool> instead of my delegate type? It can't infer the delegate type.
The following points are from the MSDN regarding Implicitly Typed Local Variables:
var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.
The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement.
It is important to understand that the var keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.
MSDN Reference: Implicitly Typed Local Variables
Considering the following regarding Anonymous Methods:
Anonymous methods enable you to omit the parameter list.
MSDN Reference: Anonymous Methods
I would suspect that since the anonymous method may actually have different method signatures, the compiler is unable to properly infer what the most appropriate type to assign would be.
My post doesn't answer the actual question, but it does answer the underlying question of :
"How do I avoid having to type out some fugly type like Func<string, string, int, CustomInputType, bool, ReturnType>?" [1]
Being the lazy/hacky programmer that I am, I experimented with using Func<dynamic, object> - which takes a single input parameter and returns an object.
For multiple arguments, you can use it like so:
dynamic myParams = new ExpandoObject();
myParams.arg0 = "whatever";
myParams.arg1 = 3;
Func<dynamic, object> y = (dynObj) =>
{
return dynObj.arg0.ToUpper() + (dynObj.arg1 * 45); //screw type casting, amirite?
};
Console.WriteLine(y(myParams));
Tip: You can use Action<dynamic> if you don't need to return an object.
Yeah I know it probably goes against your programming principles, but this makes sense to me and probably some Python coders.
I'm pretty novice at delegates... just wanted to share what I learned.
[1] This assumes that you aren't calling a method that requires a predefined Func as a parameter, in which case, you'll have to type that fugly string :/
Other answers were correct at the time they were written, but starting from C# 10.0 (from 2021), the compiler can infer a suitable delegate type (like some Func<...>, Action<...> or generated delegate type) in such cases.
See C# 10 Features - Lambda improvements.
var comparer = delegate(string value) {
return value != "0";
}; // OK in C# 10.0, picks 'Func<string, bool>' in this case
Of course the more usual syntax is to us =>, so:
var comparer = (string value) => {
return value != "0";
}; // OK in C# 10.0, picks 'Func<string, bool>' in this case
How is about that?
var item = new
{
toolisn = 100,
LangId = "ENG",
toolPath = (Func<int, string, string>) delegate(int toolisn, string LangId)
{
var path = "/Content/Tool_" + toolisn + "_" + LangId + "/story.html";
return File.Exists(Server.MapPath(path)) ? "<a style=\"vertical-align:super\" href=\"" + path + "\" target=\"_blank\">execute example</a> " : "";
}
};
string result = item.toolPath(item.toolisn, item.LangId);

What is the difference between lambdas and delegates in the .NET Framework?

I get asked this question a lot and I thought I'd solicit some input on how to best describe the difference.
They are actually two very different things. "Delegate" is actually the name for a variable that holds a reference to a method or a lambda, and a lambda is a method without a permanent name.
Lambdas are very much like other methods, except for a couple subtle differences.
A normal method is defined in a "statement" and tied to a permanent name, whereas a lambda is defined "on the fly" in an "expression" and has no permanent name.
Some lambdas can be used with .NET expression trees, whereas methods cannot.
A delegate is defined like this:
delegate Int32 BinaryIntOp(Int32 x, Int32 y);
A variable of type BinaryIntOp can have either a method or a labmda assigned to it, as long as the signature is the same: two Int32 arguments, and an Int32 return.
A lambda might be defined like this:
BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;
Another thing to note is that although the generic Func and Action types are often considered "lambda types", they are just like any other delegates. The nice thing about them is that they essentially define a name for any type of delegate you might need (up to 4 parameters, though you can certainly add more of your own). So if you are using a wide variety of delegate types, but none more than once, you can avoid cluttering your code with delegate declarations by using Func and Action.
Here is an illustration of how Func and Action are "not just for lambdas":
Int32 DiffOfSquares(Int32 x, Int32 y)
{
return x*x - y*y;
}
Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;
Another useful thing to know is that delegate types (not methods themselves) with the same signature but different names will not be implicitly casted to each other. This includes the Func and Action delegates. However if the signature is identical, you can explicitly cast between them.
Going the extra mile.... In C# functions are flexible, with the use of lambdas and delegates. But C# does not have "first-class functions". You can use a function's name assigned to a delegate variable to essentially create an object representing that function. But it's really a compiler trick. If you start a statement by writing the function name followed by a dot (i.e. try to do member access on the function itself) you'll find there are no members there to reference. Not even the ones from Object. This prevents the programmer from doing useful (and potentially dangerous of course) things such as adding extension methods that can be called on any function. The best you can do is extend the Delegate class itself, which is surely also useful, but not quite as much.
Update: Also see Karg's answer illustrating the difference between anonymous delegates vs. methods & lambdas.
Update 2: James Hart makes an important, though very technical, note that lambdas and delegates are not .NET entities (i.e. the CLR has no concept of a delegate or lambda), but rather they are framework and language constructs.
The question is a little ambiguous, which explains the wide disparity in answers you're getting.
You actually asked what the difference is between lambdas and delegates in the .NET framework; that might be one of a number of things. Are you asking:
What is the difference between lambda expressions and anonymous delegates in the C# (or VB.NET) language?
What is the difference between System.Linq.Expressions.LambdaExpression objects and System.Delegate objects in .NET 3.5?
Or something somewhere between or around those extremes?
Some people seem to be trying to give you the answer to the question 'what is the difference between C# Lambda expressions and .NET System.Delegate?', which doesn't make a whole lot of sense.
The .NET framework does not in itself understand the concepts of anonymous delegates, lambda expressions, or closures - those are all things defined by language specifications. Think about how the C# compiler translates the definition of an anonymous method into a method on a generated class with member variables to hold closure state; to .NET, there's nothing anonymous about the delegate; it's just anonymous to the C# programmer writing it. That's equally true of a lambda expression assigned to a delegate type.
What .NET DOES understand is the idea of a delegate - a type that describes a method signature, instances of which represent either bound calls to specific methods on specific objects, or unbound calls to a particular method on a particular type that can be invoked against any object of that type, where said method adheres to the said signature. Such types all inherit from System.Delegate.
.NET 3.5 also introduces the System.Linq.Expressions namespace, which contains classes for describing code expressions - and which can also therefore represent bound or unbound calls to methods on particular types or objects. LambdaExpression instances can then be compiled into actual delegates (whereby a dynamic method based on the structure of the expression is codegenned, and a delegate pointer to it is returned).
In C# you can produce instances of System.Expressions.Expression types by assigning a lambda expression to a variable of said type, which will produce the appropriate code to construct the expression at runtime.
Of course, if you were asking what the difference is between lambda expressions and anonymous methods in C#, after all, then all this is pretty much irelevant, and in that case the primary difference is brevity, which leans towards anonymous delegates when you don't care about parameters and don't plan on returning a value, and towards lambdas when you want type inferenced parameters and return types.
And lambda expressions support expression generation.
One difference is that an anonymous delegate can omit parameters while a lambda must match the exact signature. Given:
public delegate string TestDelegate(int i);
public void Test(TestDelegate d)
{}
you can call it in the following four ways (note that the second line has an anonymous delegate that does not have any parameters):
Test(delegate(int i) { return String.Empty; });
Test(delegate { return String.Empty; });
Test(i => String.Empty);
Test(D);
private string D(int i)
{
return String.Empty;
}
You cannot pass in a lambda expression that has no parameters or a method that has no parameters. These are not allowed:
Test(() => String.Empty); //Not allowed, lambda must match signature
Test(D2); //Not allowed, method must match signature
private string D2()
{
return String.Empty;
}
Delegates are equivalent to function pointers/method pointers/callbacks (take your pick), and lambdas are pretty much simplified anonymous functions. At least that's what I tell people.
A delegate is a function signature; something like
delegate string MyDelegate(int param1);
The delegate does not implement a body.
The lambda is a function call that matches the signature of the delegate. For the above delegate, you might use any of;
(int i) => i.ToString();
(int i) => "ignored i";
(int i) => "Step " + i.ToString() + " of 10";
The Delegate type is badly named, though; creating an object of type Delegate actually creates a variable which can hold functions -- be they lambdas, static methods, or class methods.
I don't have a ton of experience with this, but the way I would describe it is that a delegate is a wrapper around any function, whereas a lambda expression is itself an anonymous function.
A delegate is always just basically a function pointer. A lambda can turn into a delegate, but it can also turn into a LINQ expression tree. For instance,
Func<int, int> f = x => x + 1;
Expression<Func<int, int>> exprTree = x => x + 1;
The first line produces a delegate, while the second produces an expression tree.
Short version:
A delegate is a type that represents references to methods. C# lambda expression is a syntax to create delegates or expression trees.
Kinda long version:
Delegate is not "the name for a variable" as it's said in the accepted answer.
A delegate is a type (literally a type, if you inspect IL, it's a class) that represents references to methods (learn.microsoft.com).
This type could be initiated to associate its instance with any method with a compatible signature and return type.
namespace System
{
// define a type
public delegate TResult Func<in T, out TResult>(T arg);
}
// method with the compatible signature
public static bool IsPositive(int int32)
{
return int32 > 0;
}
// initiated and associate
Func<int, bool> isPositive = new Func<int, bool>(IsPositive);
C# 2.0 introduced a syntactic sugar, anonymous method, enabling methods to be defined inline.
Func<int, bool> isPositive = delegate(int int32)
{
return int32 > 0;
};
In C# 3.0+, the above anonymous method’s inline definition can be further simplified with lambda expression
Func<int, bool> isPositive = (int int32) =>
{
return int32 > 0;
};
C# lambda expression is a syntax to create delegates or expression trees. I believe expression trees are not the topic of this question (Jamie King about expression trees).
More could be found here.
lambdas are simply syntactic sugar on a delegate. The compiler ends up converting lambdas into delegates.
These are the same, I believe:
Delegate delegate = x => "hi!";
Delegate delegate = delegate(object x) { return "hi";};
A delegate is a reference to a method with a particular parameter list and return type. It may or may not include an object.
A lambda-expression is a form of anonymous function.
A delegate is a Queue of function pointers, invoking a delegate may invoke multiple methods. A lambda is essentially an anonymous method declaration which may be interpreted by the compiler differently, depending on what context it is used as.
You can get a delegate that points to the lambda expression as a method by casting it into a delegate, or if passing it in as a parameter to a method that expects a specific delegate type the compiler will cast it for you. Using it inside of a LINQ statement, the lambda will be translated by the compiler into an expression tree instead of simply a delegate.
The difference really is that a lambda is a terse way to define a method inside of another expression, while a delegate is an actual object type.
It is pretty clear the question was meant to be "what's the difference between lambdas and anonymous delegates?" Out of all the answers here only one person got it right - the main difference is that lambdas can be used to create expression trees as well as delegates.
You can read more on MSDN: http://msdn.microsoft.com/en-us/library/bb397687.aspx
Delegates are really just structural typing for functions. You could do the same thing with nominal typing and implementing an anonymous class that implements an interface or abstract class, but that ends up being a lot of code when only one function is needed.
Lambda comes from the idea of lambda calculus of Alonzo Church in the 1930s. It is an anonymous way of creating functions. They become especially useful for composing functions
So while some might say lambda is syntactic sugar for delegates, I would says delegates are a bridge for easing people into lambdas in c#.
Some basic here.
"Delegate" is actually the name for a variable that holds a reference to a method or a lambda
This is a anonymous method -
(string testString) => { Console.WriteLine(testString); };
As anonymous method do not have any name we need a delegate in which we can assign both of these method or expression. For Ex.
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
Same with the lambda expression. Usually we need 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);
Lambdas are simplified versions of delegates. They have some of the the properties of a closure like anonymous delegates, but also allow you to use implied typing. A lambda like this:
something.Sort((x, y) => return x.CompareTo(y));
is a lot more concise than what you can do with a delegate:
something.Sort(sortMethod);
...
private int sortMethod(SomeType one, SomeType two)
{
one.CompareTo(two)
}
Heres an example I put up awhile on my lame blog. Say you wanted to update a label from a worker thread. I've got 4 examples of how to update that label from 1 to 50 using delegates, anon delegates and 2 types of lambdas.
private void button2_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync();
}
private delegate void UpdateProgDelegate(int count);
private void UpdateText(int count)
{
if (this.lblTest.InvokeRequired)
{
UpdateProgDelegate updateCallBack = new UpdateProgDelegate(UpdateText);
this.Invoke(updateCallBack, new object[] { count });
}
else
{
lblTest.Text = count.ToString();
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
/* Old Skool delegate usage. See above for delegate and method definitions */
for (int i = 0; i < 50; i++)
{
UpdateText(i);
Thread.Sleep(50);
}
// Anonymous Method
for (int i = 0; i < 50; i++)
{
lblTest.Invoke((MethodInvoker)(delegate()
{
lblTest.Text = i.ToString();
}));
Thread.Sleep(50);
}
/* Lambda using the new Func delegate. This lets us take in an int and
* return a string. The last parameter is the return type. so
* So Func<int, string, double> would take in an int and a string
* and return a double. count is our int parameter.*/
Func<int, string> UpdateProgress = (count) => lblTest.Text = count.ToString();
for (int i = 0; i < 50; i++)
{
lblTest.Invoke(UpdateProgress, i);
Thread.Sleep(50);
}
/* Finally we have a totally inline Lambda using the Action delegate
* Action is more or less the same as Func but it returns void. We could
* use it with parameters if we wanted to like this:
* Action<string> UpdateProgress = (count) => lblT…*/
for (int i = 0; i < 50; i++)
{
lblTest.Invoke((Action)(() => lblTest.Text = i.ToString()));
Thread.Sleep(50);
}
}
I assume that your question concerns c# and not .NET, because of the ambiguity of your question, as .NET does not get alone - that is, without c# - comprehension of delegates and lambda expressions.
A (normal, in opposition to so called generic delegates, cf later) delegate should be seen as a kind of c++ typedef of a function pointer type, for instance in c++ :
R (*thefunctionpointer) ( T ) ;
typedef's the type thefunctionpointer which is the type of pointers to a function taking an object of type T and returning an object of type R. You would use it like this :
thefunctionpointer = &thefunction ;
R r = (*thefunctionpointer) ( t ) ; // where t is of type T
where thefunction would be a function taking a T and returning an R.
In c# you would go for
delegate R thedelegate( T t ) ; // and yes, here the identifier t is needed
and you would use it like this :
thedelegate thedel = thefunction ;
R r = thedel ( t ) ; // where t is of type T
where thefunction would be a function taking a T and returning an R. This is for delegates, so called normal delegates.
Now, you also have generic delegates in c#, which are delegates that are generic, i.e. that are "templated" so to speak, using thereby a c++ expression. They are defined like this :
public delegate TResult Func<in T, out TResult>(T arg);
And you can used them like this :
Func<double, double> thefunctor = thefunction2; // call it a functor because it is
// really as a functor that you should
// "see" it
double y = thefunctor(2.0);
where thefunction2 is a function taking as argument and returning a double.
Now imagine that instead of thefunction2 I would like to use a "function" that is nowhere defined for now, by a statement, and that I will never use later. Then c# allows us to use the expression of this function. By expression I mean the "mathematical" (or functional, to stick to programs) expression of it, for instance : to a double x I will associate the double x*x. In maths you write this using the "\mapsto" latex symbol. In c# the functional notation has been borrowed : =>. For instance :
Func<double, double> thefunctor = ( (double x) => x * x ); // outer brackets are not
// mandatory
(double x) => x * x is an expression. It is not a type, whereas delegates (generic or not) are.
Morality ? At end, what is a delegate (resp. generic delegate), if not a function pointer type (resp. wrapped+smart+generic function pointer type), huh ? Something else ! See this and that.
Well, the really oversimplified version is that a lambda is just shorthand for an anonymous function. A delegate can do a lot more than just anonymous functions: things like events, asynchronous calls, and multiple method chains.

Categories

Resources