Hacker News new | past | comments | ask | show | jobs | submit login

Who provides a better standard library? I am a C# developer and have not that much exposure to other standard libraries, but from what I used, .NET is by far my favorite one.



There's a fair number of patterns which are now outdated, because they were created before, e.g. Generics.

So the

  bool Int32.TryParse(string value, out number)
method would probably nowadays be better done as

  Int? Int32.TryParse(string value)
Similarly, WinForms has loads of different events of different types with individual delegates created for them. Nowadays you'd use Func and Action instead.


And they would not make arrays covariant again, the reflection API would surely use IEnumerable<T> instead of arrays, there are a couple of glitches in the inheritance hierarchy of the collections...but that doesn't really make it a bad standard library.


Nullable is not an adequate replacement for Maybe/Option, one because it is constrained only to value types, which makes it useless generically anyway, and secondly, because you can easily "bypass" it and attempt to call .Value while skipping .HasValue, causing an exception to be thrown. C# lacks the necessary features to have a useful Maybe type - namely exhaustive pattern matching and the Unit type.

A better pattern used in say, F#, would be to return the tuple of <bool, T>, which could handle reference types and value types uniformly unlike Nullable. That won't slide in C# though as there's no syntactic sugar for tuples, and calling .Item1, .Item2 is too "inelegant" for the regular programmer.

For now though, the bool Try_(_, out _ _) is still the preferred method by most.

Func and Action are certainly useful, but sometimes having a named delegate type is still preferable because you can capture the purpose of the delegate in it's name, rather than resorting to doc comments nobody is going to read anyway.


You don't need it for reference types, because those can just return a null.

I agree that it would be nice if C# checked that you dealt with the null case of the return - Resharper will happily warn me if I haven't, but it would be nice if the base compiler did. Maybe in the future!


>You don't need it for reference types, because those can just return a null.

The point is that it is not necessarily correct to conflate the nullability of the parse with the correctness of the parse. If I wanted to parse a string into a Foo, null might be a valid value for a successful parse to return, say because the rule is that the string "(null)" maps to a null Foo.


There is a draft for pattern-matching in C# [1].

[1] https://roslyn.codeplex.com/discussions/560339


Nullable is the perfect solution for TryParse. The InvalidOperationException on null is the equivalent of the NullPointerException you would expect for a reference class TryParse method.

I have implemented TryParse methods on many reference types with exactly these semantics - object on success, null on failure (often with details logged at DEBUG).


What's frustrating is how few things got the needed TLC after generics and nullables were added.

Also, I'm constantly frustrated how many core libs freak the heck out over a null string vs. an empty string. Obviously there are places to distinguish those, but if I'm trying to create a nullable int out of the text that is not one of them.


That doesn't work for a standard library - it may make you happy, but the next developer may have very different needs. Int32.TryParse() does not distinguish between null and empty strings and it takes only a minute or two to create an extension method and the problem is solved once and forever.

  public static class StringExtensions
  {
     public static Int32? ParseAsNullableInt32(this String self, Int32? fallback = null)
     {
        Int32 result;
        return Int32.TryParse(self, out result) ? result : fallback;
     }
  }


Yes, that's the obviously implementation, but so many older framework libs that have not been replaced still use serializers that, when given a Nullable type, fail to use that obvious implementation and blow up on empty strings.

In the case of the XML Serializer, that means that if I declare a class with Nullable<int> Foo {get;set;}

and

    <Foo />
appears in the XML body, then it blows up. The WebForms stuff is similarly pathetic about empty strings. There is no useful distinction between empty strings and nulls when we're talking about dates or numbers or something like that, so throwing an exception in this case is just plain wrong. It's not even protecting backwards compatibility because pre-2.0 C# didn't even have nullable ints.


Likewise Async. The basic file IO and ADO.NET APIs can be wrapped up in awaitable structures but you pretty much have to do it yourself. For most purposes if you really want to make good use of C#'s cleverest language features you have to write wrapper classes around .NET to make it work.

They've also done a terrible job of making a first class Windows UI library for .NET; WinForms was always clunky and limited in the subset of MFC/GDI it exposed; WPF was too radical and didn't make sufficient use of the underlying native capabilities of Windows - and the WinRT story has been confused from day 1.


WPF is so much better than (almost) everything else out there (that I am aware of). Yes, it is very different and switching from WinForms is hard to say the least, but it gets so many things right, is extremely powerful and really fun to use once you wrapped your head around it.


Java's library is on the whole better than C#'s. But if you want an example of a stdlib that really sets the bar then I would point to Go. In particular the io packages. They are so composable and simple and easy to use that it makes me want to cry at their beauty sometimes. Go has one of the best written stdlib's of any language I've ever used.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: