As you're no doubt aware, C# is a modern programming language following in the tradition of C, C++, and JAVA. It's full of all the standard control flow operations like for, foreach, while, do...while, if, and switch and it also attempts to remove a number of trouble spots available with its ancestors (automatic fallthrough in switch statements, pointers, memory cleanup). So one must ask, then, why the language retains the lowly goto keyword! I've read examples of using goto in languages that don't support modern control flow constructs; in that context it makes perfect sense to overcome a deficiency of the programming language using the fundamentals provided. So how does it fit in today?
The behaviour of the switch statement in C# may not be what you're expecting if you're coming from a C background because case blocks don't "fall through" by excluding a break statement. Every C# case block must contain a break statement. This is a good thing because if you inadvertently forget a break statement in a language like C, the compiler may not warn you about the omission and case blocks will continue to execute until the switch statement ends or a break statement is reached. The end result: a defect--and potentially a very significant defect. In C# if you omit the break statement compilation will fail.
At first glance this sounds like the C# language doesn't allow fallthrough in a switch statement but that's only partly true: C# doesn't allow automatic fallthrough in a switch statement. If your design requires a case block fall through you can enable this behaviour explicitly using a goto statement. If you control yourself and don't run out and replace all of your existing control flow statements with gotos, you can even use a goto without feeling dirty all over.
I lied above when I said every C# case block must contain a break statement because you can optionally replace the break statement with a goto statement. If you write your goto statement to go to the next case statement, you achieve falthrough. Moreover, if your case statements are later reordered, your gotos will preserve the original fallthrough ordering unless the gotos are also updated--a bit of a pain but worth the extra safety.
Here are two examples switching on ints and strings:
Console.WriteLine ("case 1");
goto case 2;
Console.WriteLine ("case 2");
Console.WriteLine ("case hello");
goto case "world";
Console.WriteLine ("case world");