As JB alluded to, a module is compiled the same way as a static class in C#. A static class is one that you cannot instantiate and EVERY member must be static. There are two main differences in the usage of VB modules and C# static classes:
1. In C# you must explicitly declare a class static and you must declare each member static, while in VB you don't declare a module Shared and all its members are implicitly Shared. As a side note, you cannot declare a class Shared in VB.
2. In C#, static classes follow the same naming rules as any other type. In VB, module members can be accessed without qualification, for compatibility with the same convention in VB6. For instance, if your project's root namespace is MyApp and it contains a module named MyModule and that contains a method named MyMethod, you can refer to MyMethod is any of the following ways:
MyMethod()
MyModule.MyMethod()
MyApp.MyMethod()
MyApp.MyModule.MyMethod()
The most common use for VB modules and C# static classes these days is for declaring extension methods, which cannot be declared anywhere else.
Another example is My.Resources. When you add a resource named MyResource to your project on the Resources tab of the project properties, you would usually access it in code using My.Resources.MyResource. In this case My.Resources is actually a namespace though. In it is declared a module named Resources that exposes a property for each resource. What you're actually accessing is My.Resources.Resources.MyResource but, in accordance with point 2 above, you are allowed to omit the module name any pretty much everyone does, although most don't even realise it.
EDIT: Just noticed JohnH mentioned extension methods already but at least My.Resources was news.
