4 ms·
I'm a C# developer of 10+ years. Your concerns are valid and no lost on many people. A class example being IList<T> and List<T> I was once told that a lot of t
by ed_blackburn 12y ago
I'm a C# developer of 10+ years. Your concerns are valid and no lost on many people. A class example being IList<T> and List<T>
I was once told that a lot of the original libs were effectively ported from C++ libs by C++ devs in a hurry. There are nuget packages with decent data structure / collections missing from the core BCL.
Interfaces like IEnumerable<T>, IComparable<T> and IEquatable<T> I find to be extremely useful and if you're following interface segregation principle and not chucking round the actual concrete implementations. I concede though that the BCL would be richer if one didn't have to think about this stuff too much.
I guess there's enough experienced C# devs around to know how to avoid those pitfalls. As the BCL is shrunk I expect it will be easier to substitute any structures your not happy with, with alternatives.
- sparkie 12y agoIn a hurry is an understatement. Generics were allegedly implemented by Don Syme before the initial release of C#, but higher ups were more keen on shipping a substandard product because Generics were "only for academics". Some of C#'s interfaces are simple and well designed, but the OOP model used is kind of weak for composition of them. For example, one would often like an IIndexable interface to cover both arrays and lists, or an numeric interface for which we can perform common operations over any number type. Without the ability to extend existing implementations with new interfaces, we're stuck using various patterns and wrappers to get the abstraction we need. I was a C# developer for about 6 years before I got tired of the same old problems and decided it's not for me. I still use it occasionally when required, but not if other options are available.
- noblethrasher 12y ago> For example, one would often like an IIndexable interface to cover both arrays and lists I’ve thought about this. To be useful, an IIndexable would need get and set methods for the index, and a Length/Count property. You would need to explicitly implement it on something like the array class since you wouldn’t want to lose the semantic difference between Length (O(1)) and Count (O(n)). But, the existence of Func<T, TResult> and Action<T1, T2> would largely obsolete the utility of such and interface. Let xs be an “indexable” object of T (e.g. T[] or List<T>). Then any method that expects to only access an object could just accept lambda of type int -> T. So, you’d just pass it n => xs[n]. Similarly, methods that expect to mutate the object could take a lambda of type (int, T) -> (). So would just pass something like (n, x) => xs[n] = x. This is nicer because it makes explicit what the method will do to the indexable.
- danbruc 12y agoI don't think there is the distinction between Length and Count you draw - Count is O(1) for most collections, even LinkedList<T> maintains the number of elements in the list in a separate field. You could say Length does not change during the lifetime of an object while Count may do so, but I am not even sure if this distinction is always honored.
- noblethrasher 12y agoYes, I think you're right. I thought that I had read stuff about the name implying the complexity class, but my Google-Fu isn't turning anything up.
- ickoonite 12y agoArrays actually do implement IList<T>; they did think of that. I guess the problem is that it's not discoverable. I'd second your call for an interface on numbers (including some way to "genericise" TryParse).
- sparkie 12y agoArrays implementing IList<T> is a clear example of a broken abstraction though - arrays have no need for Add, Remove and whatnot that come with IList - it only needs indexing and count.
- cema 12y agoYeah. Although dynamic arrays would need that.
- noblethrasher 12y agoWe normally think of Strings as being a special case of an array, but arguably String<T> should be a fundamental datatype, and we could do away with Array altogether. In that case, having operators for add and remove doesn't seem so crazy, especially in light of the fact that vectors often outperform doubly linked list for insertion and deletion on modern hardware[1]. [1] https://www.youtube.com/watch?v=YQs6IC-vgmo https://www.youtube.com/watch?v=YQs6IC-vgmo
- cema 12y agoI guess the problem is that it's not discoverable. I think you are absolutely right. While the reflection is available (and the documentation, in general, is not at all bad), discoverability is still weak.
- _random_ 12y agoWhich language did you switch to?