1) Simply write a quick extension method (not ideal but not a reason to switch languages):
var xs = r.YourExtensionMethod<int>(rr => rr.GetInt(0)).ToList();
2) Simply use the appropriate built-in method: int f(string x)
{
int number; /*Will be not necessary in C#6.*/
return Int32.TryParse(value, out number) ? numeber * 3 : -1;
}
3) It's a matter of taste. Not a bad feature, but not a killer one either.But it sure all adds up.
Switching for a codebase might not be a wise move for many reasons. But writing new code doesn't have those excuses.
Actually workflows are the closest to a "killer" feature but C# took the most popular, async, and hard-coded it in.
I'm not sure how new List<string> { "a", "b" } is more readable than new List<_> {"a", "b"), but hey, sure, if you want to argue type inference is bad, go for it. F# also lacks loop constructs like break/continue.
I don't feel I've misrepresented C# at all to make it look bad. I've written a lot of C# code and a fair amount of F# code. Line by line, char-by-char, expression-by-expression, F# is simply much less code. Those examples are just things off the top of my head, from real codebases.
C#'s alright, because the competition (like Java) is laughable. So in that sense, it's "great". In absolute terms, it doesn't measure up (and this isn't a secret, bit-by-bit C# adopts features F# proved out.)
Units-of-measurements are implemented via erasure, yes. How would you represent float<m> externally to make it available to common types, but without losing performance? The compiler consuming them would need to be aware of it. And at runtime, you certainly don't want extra overhead, and I don't think the CLR has any efficient way of exposing primitives with additional type info. It's an unfortunate tradeoff.
F#'s benefit will come as a bunch of tiny improvements, "programming in the small" as they call it. For instance:
In C#, it's: Or: In C#, it's uglier. First because try... isn't an expression. Second, because you cannot shadow variables by rebinding them, so you always have to keep "old" vars around and in scope, and cannot reuse handy variable names: Or: In C#, you've got to declare x outside a block: Which is more annoying than it might seem. How much nicer is it to be able to create a new scope at any point in a function, and return a value out of it cleanly?These are by no means a complete or even important showcase of C#'s lacking. Just a few quick thoughts off the top of my head. In general, every time I'm writing C# code, I keep realising how things would be much more concise if I was in F#.