Shared memory usually is not an acceptable implementation technique for these kinds of things, except when used point-to-point, or between a pool of very closely related processes. If one of the processes crashes the memory is left in a inconsistent state. There nothing preventing a rogue process from writing all over it while the others are running. And so on.
Worse, how does it work if one of the process is privileged? I smell a giant security whole right there.
The only robust solution is to have central "server" process (ala Wine). I think the performance overhead and additional complexity of such a solution are obvious.
Not to mention that the benefit of mandatory locking between cooperating processes a little dubious :-)
But my bigger point was that such workarounds (not to mention potential security vulnerabilities) and the complexity they bring should not be needed and are not desirable in a Linux programming language. When developing, administering or debugging something sufficiently complex in Linux, the last thing anyone needs is an additional tangle of semi-emulated Win32 semantics.
I am not bashing Mono or other .NET re-implementations - I think it is a great product - but in my mind it is primarily a vehicle for porting Win32 .NET apps to Linux, and not really an ideal tool for Linux-only development.