As Chris mentioned you could expose a C# dll as a COM component. If you do it this way it would be ideal that you manifest the C# COM component in your main executable if you have one, rather than registering it with regasm /codebase and save yourself DLL hell. Makes for much easier deployment and no UAC involved.
When you manifest a component you must remember that the C# also needs a manifest as activation code.
Remember if you decide to go COM you need to register an exception handler and manage those exceptions. You have to have a local working storage section for that to work.
Another option is to create a C# managed assembly with unmanaged entry points. So to COBOL this looks like a C++ DLL. (google RGiesecke.DllExport;) You can then in COBOL, perform a LoadLibraryA, followed by GetProcAddress, then execute the procedure. Depending on what you're passing back you might have to clean up memory with CoTaskMemFree.
I use both methods, started of using COM and then moved to C# with unmanaged entry points. The C# with unmanaged entry points became a 'gateway' type dll, where I could get the gateway to load other managed assemblies and execute methods within them, you could of course do that with the COM dll as well.
Neil