Learning to program for the .NET Framework has been an interesting experience. I use the term "interesting" loosely: it has sometimes been amazingly easy, and sometimes unexpectedly frustrating.
For instance, I was writing a simple chat application with Windows Forms in C# and thought it would be good to grab the users' workstation and login names to identify each participant, rather than generate yet another CB-type handle like the instant messenger programs do. "Simple," I thought, "I'll just call
GetUserName and
GetComputerName." But when I searched the .NET Framework documentation for those Win32 API functions, I couldn't find them.
After a little bit of browsing, I gave up. "Well," I thought, "I can always use P/Invoke," meaning the Platform Invocation facility in .NET used to call DLL functions. "That shouldn't take more than a couple of minutes to set up."
I looked up the first Win32 API function:

BOOL GetUserName(
LPTSTR lpBuffer, // name buffer
LPDWORD nSize // size of name buffer
);
The GetUserName function is implemented in advapi32.dll, so I added the following code to my C# program:
using System.Runtime.InteropServices;
//...
[DllImport("advapi32.dll")]
public static extern bool GetUserName( _
Byte[] lpBuffer, int nSize);
//...
Byte[] b=new Byte[100];
int n=100;
bool rc=GetUserName(b, n); //kaboom!
Here
System.Runtime.InteropServices is the namespace that supports
DllImport, and
DllImport is an attribute that means you're importing an unmanaged function from a DLL.
When I ran that code, I discovered that it threw a
System.NullReferenceException when it tried to call
GetUserName.