Code obfuscation goes well beyond simple renaming of classes, members and variables, though that's an important part of it.
For example, Dotfuscator uses a patented technique called overload induction, where many methods are renamed to the same name (this is possible as long as they have different signatures). PreEmptive solutions cite cases where a third of all methods in the code are renamed to a(). Other techniques involve rewriting simple iterations as recursion, as well as code morphing.
Actually, modern obfuscation techniques are perfectly adequate for making code virtually impossible to reverse-engineer, at least by hand. While it is true that .NET assemblies can never be RE-safe in principle, obfuscation can provide a pretty formidable barrier.
For most of us, that's enough.