The other answers which note that C# has no built-in support whatsoever for function pointers, even in unsafe mode, are correct.
It is interesting to consider what it would take to implement this feature. As it happens, I have implemented this feature in an unreleased prototype version of C# back in... 2010? Around then. Maybe 2011.
We decided upon review of the prototype that the syntax was insufficiently pleasant and the usage cases were insufficiently compelling to justify going forward with the feature.
First off, what is the compelling benefit of the feature over delegates? Delegates are typesafe and nicely capture the semantics of a reference to a function bound to its receiver. However, in some "systems" scenarios -- the same scenarios in which you would be using raw pointers to memory in the first place -- delegates are simply too heavyweight. They are garbage collected, they increase collection pressure, they're a large object compared to the size of a pointer, they have costs on every invocation, and so on. Or, you might be constructing your own custom layout vtables to interoperate with some particularly nasty bit of unmanaged code, and you wish to invoke a function pointer that you've just put down in your vtable. And so on.
The CLR has the necessary instruction:calli
, a pointer-indirected call. But there is no syntactic construct in C# whatsoever that will cause the C# compiler to emit this instruction.
So what's the problem? Just add some syntax that causes this to be emitted, right?
The problem is: what syntax? In order to ensure that the CLR's physical stack remains aligned correctly, the compiler must know the signature of the method being invoked via the pointer. Of course we already have a mechanism for saying what the signature of a method is: that's called a delegate, and we've already rejected the use of such a thing. Moreover, remember, we are talking here about the physical stack that is actually going to be manipulated, not the CLR's abstract evaluation stack. The signature of the function invoked must include things like whether the function pointer is cdecl or syscall, for instance.
We struggled for some time to come up with something that did not look hideous, and whichever way we tried, it looked more hideous. I actually do not recall what notation we ended up implementing for the prototype; I think I may have blocked it out. I might have it in my notes somewhere, but unfortunately I do not have time to look right now.
The feature is still brought up every now and again. The current management of the C# team has a history with using managed languages in low-level applications, so now might be a good time to pitch it again if you have a strong use case.