The delegates in C# offer similar functionality as function pointers in C. I heard someone saying "C# delegates are actually better than function pointers in C". How come? Please explain with an example.
-
Whoever said that can explain better what they mean by that, no? – Victor Mar 29 '10 at 02:42
-
Actually I read it in a book long back. I don't remember which book. But now I'm using function pointers in my C code. So, just remembered. – pecker Mar 29 '10 at 02:44
-
It is strongly typed, first class data type (like class) and you can define inline delegate as well. These are some advancement to function pointer in C/C++ – Fadrian Sudaman Mar 29 '10 at 02:50
4 Answers
"Better" is subjective -- but the main differences are:
- Type safety. A delegate is not only guaranteed to refer to a valid method, it is guaranteed to refer to a method with the correct signature.
- It's a bound method pointer -- that is, the delegate can point to a specific object on which to call the delegate. Thus, an
Action<string>
delegate could refer toalice.GetName
orbob.GetName
rather than justPerson.GetName
. This might be similar to C++ "pointer to member" -- I'm not sure.
In addition, the C# language supports closures through delegates to anonymous methods and lambda expressions -- i.e. capturing local variables of the declaring procedure, which delegate can reference when it later gets executed. This isn't strictly speaking a feature of delegates -- it's enabled by the C# compiler doing some magic on anonymous methods and lambda expressions -- but it's still worth mentioning because it enables a lot of the functional idioms in C#.
EDIT: As CWF notes in comments, another possible advantage of C# delegates is that the delegate type declarations are easier for many people to read. This may be a matter of familiarity and experience, of course.

- 73,686
- 17
- 161
- 157
-
Type Safety: Isn't that the case with all kinds of pointers in C/C++? Isn't it the matter of compiler we are using? I mean, if my compiler throws an error if I point a function pointer to int. Then wouldn't that be type safe? – pecker Mar 29 '10 at 02:49
-
No, because you could declare a pointer to a `int f(int)`, set it to the address of an `int f(int)`, then cast it to a `char* f(long)`. Or `void* badptr = "random garbage"; INT_FN ohno = (INTFN)badptr; int pwned = ohno(123);` (where INTFN is a typedef for `int f(int)`, I just can't remember the C++ declaration syntax \*grin\*). Whereas C# will fail the evil cast. – itowlson Mar 29 '10 at 02:53
-
2Type safety is more an issue of the language than the particular language feature. That said, the only think you left out is syntax. Function pointers declarations in C (and probably C++ when not using Boost) can be difficult to unravel. But delegate declarations are easy. Also, lambdas are a special case of delegates (I think), and they are so very very useful sometimes. – CWF Mar 29 '10 at 02:53
-
3Woah, don't throw in closures as an "in addition to" thing. Closures are a huge friggin' deal enabling a whole new style (functional) of programming. – George Mauer Mar 29 '10 at 02:59
-
1George, I agree that closures are a huge deal... *but* arguably closures are an artefact of C#'s anonymous methods and lambda expressions, rather than part of the delegate system per se. Obviously, anonymous methods and lambdas couldn't exist without delegates -- but delegates *in and of themselves* don't provide closures. But I may be splitting hairs here -- I definitely agree with you on the importance of the feature! – itowlson Mar 29 '10 at 03:27
Pointers can always point to the wrong place :) I.e it can point to a non-function or an arbitrary place in memory.
But in terms of functionality, function pointers can do anything that delegates can do.

- 10,126
- 9
- 43
- 46
-
3Just a note that it's hard to overstate how big of a deal this is. That a c++ function pointer is still just a pointer deep down allows for all kinds of badness in terms of tricking one to point to malicious code. An otherwise unremarkable buffer overflow can suddenly become much easier to exploit. – Joel Coehoorn Mar 29 '10 at 02:42
-
Joel, no argument with you there! I think that's the main advantage of Java over C++ -- eliminating pointers meant eliminating a whole slew of ;roblems. – Larry Watanabe Mar 29 '10 at 21:16
One thing that a delegate provides that a C/C++ function pointer doesn't is type safety. That is, in C/C++, you can shove a function pointer into a function pointer variable declared with the wrong function signature (or even an int a double or worse with appropriate coaxing), and the compiler will be happy to produce code that calls the function completely incorrectly. In C#, the type signature of the function must match the type signature of the delegate and also the way the delegate is ultimately called.

- 26,911
- 4
- 71
- 95
-
Isn't that the case with all kinds of pointers in C/C++? Isn't it the matter of compiler we are using? I mean, if my compiler throws an error if I point a function pointer to int. Then wouldn't that be type safe? – pecker Mar 29 '10 at 02:48
-
Well, sure. Your compiler can warn you when you casually try to put something in a slot that it shouldn't fit. I wouldn't argue that you shouldn't use function pointers if you're writing code in C++--sometimes that's just the right language for what you're doing. – sblom Mar 29 '10 at 02:55
Many people refer to C# delegates as more "type-safe" than C++ function pointers and I really find it misleading. In reality they are no more type-safe that C++'s function pointers are. An example C++ code (compiled by MSVS 2005 SP1):
typedef int (*pfn) (int);
int f (int) {
return 0;
}
double d (int) {
return 1;
}
int main()
{
pfn p=f; // OK
p=d; // error C2440: '=' : cannot convert from 'double (__cdecl *)(int)' to 'pfn'
p=(pfn)d;
}
So as is seen from the example above unless one uses "dirty hacks" to "shut up" the compiler the type mismatch is easily detected and the compiler's message is easy to understand. So that is type-safety as I understand it.
Regarding the "boundness" of the member function pointers. Indeed, in C++ pointer-to-member is not bound, the member function pointer has to be applied to a type variable that matches the member pointer's signature. An example:
class A {
public:
int f (int) {
return 2;
}
};
typedef int (A::*pmfn) (int);
int main()
{
pmfn p=&(A::f);
// Now call it.
A *a=new A;
(a->*p)(0); // Calls A::f
}
Again, everything is perfectly type safe.

- 11
- 1
-
Type safe til you cast to a `void*` and back. Then that pointer will appear to be anything you want, but break when you try to actually use it. C# makes such trickery very difficult, if not impossible. – cHao Sep 06 '10 at 14:25
-
1@cHao nope, C++ doesn't allow for implicit conversion from void* to other* (it allows implicit conversion in the other direction). That's C you're talking about. As for making such trickery difficult (no way in hell it's impossible), I think that's overkill, just don't make it easy to do by accident and leave the rest up to the programmer (i.e. trust the programmers to use their brain). – Giel Aug 22 '11 at 12:48