I don't buy the types as safety argument. Types are a very, very poor code contracts. You can enforce contracts in dynamic languages too. Also, poor man's immutability. So what if I can't change int a into "foo", I can change it into 6 and that might totally change the behavior of the program. Erlang is an example of a language that is dynamic but has first class support for contracts and immutability is completely enforced. A dynamic language that is used to build routing and switching equipment that is expected to be totally impervious to anything.
I don't really believe type problems cause many bugs, it's more the contents of the types (passing bad values) that cause bugs and static typed languages don't help there. Again, code contracts help and immutability makes it a bit easier to guess certain things about the behavior of the code.
I've also done C# professionally (not nearly as long as Java), and while I agree it is better language than Java, I think it's feels like a dated approach. It's too much like Java.. And I prefer Java and all it's memory management over C++. That covers all the mainstream static languages I think.