- typechecked, but the types get out of the way; "var" and intellisense fill them in for you. It also shows you what types the function arguments should be and autosuggests objects of those types
- functional when you want, but not when you don't: LINQ et al, interlinkage with F# if you want to get really functional, now immutable record types. Lambdas.
- wordy enough that you can see context, but Intellisense means not having to type it out
- smart refactoring (paid-for Resharper)
- debugger when you need it: run test case. Wait to hit exception or breakpoint on failed assertion. Inspect values. It's often immediately obvious where the problem was.
- CPU and memory profilers readily available and well integrated.
- standardised on Nunit with Nsubstitute for testing: bit wordy, but with a bit of thought we're now hitting 100% line coverage on wholly new code.
- portable ish binaries with Mono
- package management system is mature. (Wart: packages are at the "project" rather than "solution" level in VS, so you need to do extra work to ensure they're all the same version)
The only real downside is the build system (MSBuild) is pretty poor, badly documented, and not easy to use for other things than C#.
For the future? "Software components" have never quite delivered. Package management is clearly the frontier here.
Language interoperability is another: it's still astonishingly hard to combine languages within a single software artefact unless they're C and C++ or similar things that produce platform-native binaries. Proliferation of language runtimes makes this worse, not better. On the other hand, the two frontrunner runtimes of C# and Java both have problematic owners.