Typically, branching of any kind (switches, if-statements, loops with non-constant iterations) are best avoided. This is mildly true on the PC (not enough to be worth worrying about at all outside of very tight inner loops), especially true on some general-purpose CPUs like the 360's Xenon (common hardware that makes indirect references on branches tolerable on modern super-scalar out-of-order deep-pipeline CPUs was left off the Xenon to save on cost), and especially true on GPUs.
GPUs are very special beasts. They do not work like a general-purpose CPU. They run potentially thousands of copies of a shader at a time, and there are limitations imposed on the hardware to make this possible. One of these limitations is that a number of execution cores share resources. For sake of example, let's say 4 cores are tied together like this on our hypothetical GPU.
So at any time, four "core" are running a shader in lock-step. They share an instruction pointer. They sort-of share a register file. The SIMD behavior of your shaders is not like SIMD behavior on the CPU which is typically used in games; each shader isn't doing four-way vector operations at once, but rather, all four cores work on a single component from the four different data streams at once. These four cores are tightly tied together.
The shared instruction pointer is key. If two of your shaders in this group execute switch case 1 and the other two run switch case 2, all four cores must run both switch cases! Predicated instructions are used to ensure that the results of the instructions in the "off" case are ignored for a particular core, but it still takes the time to execute the instruction and do any memory/register/texture accesses (which is why you should only do texture lookups in uniform code paths), etc.
Hence, branches are "slow" in the fact that your hardware ends up really under-utilized. A potentially very large portion of it ends up spending time evaluating instructions that have no effect. This is different than the CPU case where branches hurt because of pipeline stalls and mispredictions; the GPU often has very restricted branching capabilities anyway.
Is this "slower" than swapping out shaders? That depends. If you batch up your draw commands such that you do all draw operations using a particular shader in a row (so you don't switch from shader A to shader B and then back to shader A, but rather do all drawing with shader A and only then do drawing needing shader B)... it still depends, but it will probably be faster with this batching. As will all things performance-related, you need to test and find out specifically for your application and target hardware. If your switch statements are simple enough you might find that it is indeed quicker to use them.
It is often better anyway to batch up object with identical material properties (same shaders, textures, material constant buffers, etc.) just to avoid changing active resources even when using an uber shader. Breaking up your shaders to play well with this is often not hard at the low-end of the graphics scale. It can get to be a bit more difficult with multiple material types in a deferred shading context, and here a semi-uber shader approach is typically taken (often just for BRDF calculations and the like).
Note that engines like CryTek have taken the uber shader approach (unsure if the most recent incarnations still do), so it's certainly usable for very high-end games in the real world.
switch()
has to be evaluated every time the shader runs, i.e. for every pixel drawn. If you keep your shaders separate, there is no extra work per pixel. But don't take my word for it...why not code up both versions and measure the performance? \$\endgroup\$