The ugly part of the dictionary is the type parameters, but I can't see a workaround for that without some really hard type-inferencing for all generics. I mean, you'd have to infer the type-parameters of a generic class based on the type-parameter of the IEnumerable passed into its constructor (dictionary takes an IEnumerable of KeyValuePairs of TKey, TValue). That's a little messy.
> let myd = dict [ "a", 1; "the", 2; "train", 3 ];;
val myd : System.Collections.Generic.IDictionary<string,int>
> let myd = dict [ "a", System.String.IsNullOrEmpty ];;
val myd : System.Collections.Generic.IDictionary<string,(string -> bool)>
If C# had tuples, then you might be able to do something like: var myd = createdict(new[] { {"a", 1} , { "the", 2} ...})
The tuples should get a type inferred, then the array, then that can pass the type to createdict and all good. And the array could be removed if there was some other sort of list-like literal. This might be really difficult to implement in the C# compiler, for all I know.More likely, they'll graft in yet another special rule in the compiler (not accessible to user code!), just as they did with other collections, foreach, async, etc. I find it ugly that the compiler is happy to use static duck typing when convenient, but such a feature isn't exposed in the language.