I always thought of C# as the improved, less verbous Java. I wouldn't compare it with Python or other dynamic languages, but I prefer it to most compiled languages (especially at the times it was created)
I always thought of C# as the improved, less verbous Java. I wouldn't compare it with Python or other dynamic languages, but I prefer it to most compiled languages (especially at the times it was created)
public static IList<Ephraimite> FindEphraimitesToKill(IList<Ephraimite> ephraimites)
{
IList<Ephraimite> ephraimitesToKill = new List<Ephraimite>();
foreach (Ephraimite ephraimite in ephraimites)
{
if (ephraimite.Speak("shibboleth") == "sibboleth")
{
ephraimitesToKill.Add(ephraimite);
}
}
return ephraimitesToKill;
}
Now, the same in (imperative-style) OCaml: let findEphraimitesToKill ephraimites =
let ephraimitesToKill = ref [] in
List.iter (fun (ephraimite) -> begin
if speak(ephraimite, "shibboleth") = "sibboleth" then
ephraimitesToKill := !ephraimitesToKill @ [ephraimite]
end) ephraimites ;
ephraimitesToKill;;
See how much less we had to specify the type of what we're handling here? And things would have gotten easier if we used functional-style OCaml, but that's not entirely a fair comparison.So hypothetically it should be possible to write a C# compiler that would, if type annotations were omitted in some places, be confident enough to assign a sensible default, which is why we call the current version verbose. Although I suppose it's slightly more complicated than that. (Interfaces, if we want to have them, need to be explicitly declared as there are potentially many interfaces that could be used for a given object, and the rigidity imposed by redundant type declarations could help with the health of large and long-lived codebases.)
public static IList<Ephraimite> FindEphraimitesToKill(IList<Ephraimite> ephraimites)
{
var ephraimitesToKill = new List<Ephraimite>();
foreach (var ephraimite in ephraimites)
if (ephraimite.Speak("shibboleth") == "sibboleth")
ephraimitesToKill.Add(ephraimite);
return ephraimitesToKill;
}
or: public static IList<Ephraimite> FindEphraimitesToKill(IList<Ephraimite> ephraimites)
{
return ephraimites.Where(e => e.Speak("shibboleth") == "sibboleth").ToList()
}
is not that verbose.The C# style guide of a former employer of mine (an enterprise C# user) forbids both of these snippets because of the unbraced statements in the former and the LINQ and lambdas in the latter. But admittedly I don't know what's common among C# users, so maybe they were in the minority.
The "required brackets" is more common but I think it's a good rule :). Readability is only slightly hindered by the extra brackets, but I've seen quite a few errors from
if(shibboleth)
DoSomething();
DoSomethingElse();The LINQ version should be allowed almost everywhere that has a good development group. Sometimes LINQ queries can get hairier than the equivalent foreach, but I've never worked anywhere that would frown upon the shorter/cleaner LINQ.
I don't like the version without brackets, but I don't think it would make the code less compact if you'd add brackets.