32

In podcast 73, Joel Spolsky and Jeff Atwood discuss, among other subjects, "five things everyone should hate about their favorite programming language":

If you’re happy with your current tool chain, then there’s no reason you need to switch. However, if you can’t list five things you hate about your favorite programming language, then I argue you don’t know it well enough yet to judge. It’s good to be aware of the alternatives, and have a healthy critical eye for whatever it is you’re using.

Being curious, I asked this question to any candidate I interviewed. None of them were able to quote at least one thing they hate about C#¹.

Why? What's so difficult in this question? It is because of the stressful context of the interview that this question is impossible to answer by the interviewees?

Is there something about this question which makes it bad for an interview?


Obviously, it doesn't mean that C# is perfect. I have myself a list of five things I hate about C#:

  • The lack of variable number of types in generics (similar to params for arguments).
    Action<T>,
    Action<T1, T2>,
    Action<T1, T2, T3>,
          ⁞
    Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>
    Seriously?!

  • The lack of support for units of measure, like in F#.

  • The lack of read only properties. Writing a backing private readonly field every time I want a read only property is boring.

  • The lack of properties with default values. And yes, I know that I can initialize them in the parameterless constructor and call it from all other constructors. But I don't want to.

  • Multiple inheritance. Yes, it causes confusion and you don't need it in most cases. It's still useful in some (very rare) cases, and the confusion applies as well (and was solved in C#) to the class which inherits several interfaces which contain methods with the same name.

I'm pretty sure that this list is far from being complete, and there are much more points to highlight, and especially much better ones than mine.


¹ A few people criticized some assemblies in .NET Framework or the lack of some libraries in the framework or criticized the CLR. This doesn't count, since the question was about the language itself, and while I could potentially accept an answer about something negative in the core of .NET Framework (for example something like the fact that there is no common interface for TryParse, so if you want to parse a string to several types, you have to repeat yourself for every type), an answer about JSON or WCF is completely off-topic.

21
  • 54
    Why the question “give five things you hate about C#” is so difficult to answer Because it's a list question, and an evil mod would close it as "not constructive" before you get the chance to answer it... ;P
    – yannis
    Aug 6, 2012 at 20:57
  • 6
    @Yannis Rizos: good point. BTW, when typing this question in a title, Stack Overflow warns that "The question you're asking appears subjective and is likely to be closed." Aug 6, 2012 at 21:02
  • 5
    Perhaps your brain's storage space for things to hate about programming languages is mostly filled with aspects of the other languages you have to deal with. Aug 6, 2012 at 21:14
  • 10
    Probably because most people aren't hateful. Hate is a pretty strong word to most people. Judging by the list of really, really trivial items that you "hate" about C#, man I would really not like to be anywhere near you when there is some reason to actually hate something. I suspect your head would explode. I also suspect coming up with a list is hard for most people since you had to really stretch to come up with your list and you had days to think of it.
    – Dunk
    Aug 6, 2012 at 23:27
  • 19
    Did you notice how all items on your list were about something missing rather than something done wrong. In my view you failed the interview question. Everyone can list features missing from the language and declare it a reason to hate but the most hated language will be the one that has all the features.
    – Stilgar
    Aug 6, 2012 at 23:52

10 Answers 10

43

If I would have to guess:

  1. Some programmers lack diverse language exposure. It's hard to see things wrong with the language when you don't know that better things exist.

  2. Some programmers are mere code monkeys. They barely analyze the problems in front of them, let alone something like how their programming language could be better.

  3. Few people are particularly critical. They see benefits and features, not shortcomings. It is hard for them to shift into that mode of thinking if the interview isn't going that way.

  4. At least around here, being overly critical is seen as a fatal personality flaw. Instead of being 'that insightful developer that is always looking for better ways of doing things' (like some areas I've lived), they are 'that asshole that hates everything'. Even people who can think of things they hate in the language might defer in an interview setting to seem less acerbic.

4
  • 25
    As for no 2, we prefer Software Simians, Sir. Aug 6, 2012 at 21:34
  • @Tom I thought it was pan programmatoribus. Aug 6, 2012 at 21:56
  • 10
    @Telastyn shouldn't there be five bullet points in your answer? Aug 7, 2012 at 0:18
  • #4 is what came to my mind immediately, particularly in work environments that are committed to using C#. Considering common interview and workplace behavior advice, being asked this in a job interview may seem like bait to catch "bad attitudes" that might make them not want to hire that person. Unlike legal prosecution, in job interviews entrapment is unlikely to be an effective defense. ;-)
    – Dronz
    Nov 24, 2014 at 18:51
36

I would imagine that the question is so hard to answer during an interview because it's:

  1. Really unexpected,

  2. Requires a lot of thinking, and a thinking in a very different way from the one used during an interview,

  3. Is hard to answer in general in a short amount of time (unless prepared before the interview).

1. It's unexpected

Unexpected questions are truly hard, especially in a stressful context. Imagine the following dialog during an interview:

‒ What's the difference between HashSet<T> and List<T>?
‒ The hashset is optimized in a way that the search for an element is very fast. For example if you're using set.Contains() within a loop lots of times, moving the set from list to hashset may make things faster.
‒ How do you create a read only property?
‒ I use a field marked as readonly as a backing field for a property which has only a getter.
‒ What is the usage of sealed?
‒ You use it for classes which must not be inherited.
‒ What's the last time you've seen a dentist?
‒ What?!

2. It requires a lot of different thinking

When you're asked general interview-type questions, you're using your memory to recall what you've learnt from books or from your practice about the language and the framework. You may think a bit in order to find an answer, but not too much.

On the other hand, the question about the five things you hate requires a deeper thinking. You can't just recall something you've learnt from books, and you can't find anything by analogy. Instead of being passive, you have to be critic and find what could be unpleasant in the language you use.

3. It requires time

Frankly, I have my list of five (actually more) things I hate about C#, but I thought about it over a long period of time. A few things are from the .NET Framework 2 era; most issues I listed for .NET Framework 2 are no longer valid because they were removed, some with LINQ and all this functional programming stuff, others with dynamic programming. I'm not sure if, without preparing this question, I would be able to find all the five elements during an interview.

4
  • 3
    I think you're generally right, but programming in a certain language for enough time will simply make you hate certain 'peculiarities' of it. Like a hit list of some sort. Or at least I have one for each language/platform I've ever used. Or maybe I'm just spoiled and picky.
    – K.Steff
    Aug 6, 2012 at 21:13
  • 2
    @K.Steff: "Hit-list" is a perfect name for it :). I can certainly think of far more than five problems with even my favorite platform; if you ask me about a language I don't like but have been forced to use (e.g. Java or Python) I could probably go on for hours :P. Aug 6, 2012 at 21:22
  • 1
    Whether you can easily remember those things you hate in a language will depend on how troublesome the 'peculiarities' are relative to other things you have to deal with. For example, most of my work involves interacting with a certain (and particularly terrible) foreign system and its API. Most gripes about C#/.NET pale in comparison and get pushed to the back of my mind.
    – Dan Lyons
    Sep 12, 2013 at 17:36
  • It is wonderful that you can keep track of a "hit-list" for each language/platform and carry it around with you as you've been programming in a certain language for "enough time". Then there are others who just don't bother to carry those issues around after programming for "enough time". What others do is figure out a solution to the problems in their hit-list and then never have to worry about the hit-list problem again because they made it go away. If it was problem enough to carry around a list then they must have thought it was problem enough to take the time to solve to their liking.
    – Dunk
    Apr 28, 2014 at 21:37
22

I think it's difficult because of the word five. And to a lesser degree, because of the word hate.

Five? What if you only come up with four? Have you failed to answer the question? What if you have more than five? Now, on the spot, you have to figure out which of those are the best five to use.

Hate is a very negative word. It's the kind of negativity that people are told to avoid in interviews. Moreover, I think it would sound odd to a lot of people to have that many things they "hate" about a language they'll be spending all day programming in. Some people might even think it's a trick question: If they actually do come up with five things, they'll be disqualified for hating C# too much to program well in. Unfortunately, this kind of perverse trick question is not unheard of in interviews.

Instead, you could ask What would you improve about C# if it were up to you? This allows the interviewee to answer with any number of things. This phrasing also trades the negativity of the word "hate" for the relatively positive "improve."

2
  • 2
    Your point against "five" is a good one--many people will probably have a continuum of things they dislike in varying degrees, but the only way they could decide which things represent the top five would be to rank everything that might be close. If someone has just recently had trouble with something that's generally a minor annoyance, they may have to think awhile to figure out whether it should really make the top five, or if it just came to mind because it was an issue so recently. Further, C# is so intertwined with .NET that it's hard to say what to blame on what. For example...
    – supercat
    Feb 16, 2014 at 17:54
  • 1
    ...I would posit that all languages should guarantee that if a constructor throws, the partially-constructed object will get Disposed, but absent a requirement that all languages enforce that, one can argue that languages which do so would invite false expectations. It may thus be unclear whether the difficulty of avoiding resource leaks on C# constructor failure should be blamed on C# or the CLS.
    – supercat
    Feb 16, 2014 at 18:03
14
  • Most candidates aren't that deeply involved with more than one language or paradigm in order to contrast. I haven't worked with another object-oriented language for over 5 years now, and the one I had been working in (PowerBuilder), I had a lot of peeves with. Most guys fresh out of college are (or think they are) hot stuff at one, maybe two languages, and have received "exposure" to three or four more (meaning they completed at least one homework assignment requiring it but less than a full semester course studying it). That's not enough knowledge or experience to really know what's wrong with the language. Get a job in the real world, and that focus narrows considerably; you learn a lot more about the language that gets you the paycheck than any other, and in the process, you come to accept what the language won't do, or does in a weird way, to the point where you couldn't remember doing it differently.

  • Most C#-savvy candidates who compare it to Java/C/C++ are pretty happy with it. C# was designed from the ground up to do a lot of things better than Java (events, callbacks, the graphics library, database work). Java in turn was designed to be easier to use, and so more focused on correct code, than C++. I've yet to meet a C# programmer who wants to go back to C++ in any environment where blistering performance and near-circuit-level control aren't critical necessities.

In other words, See-Sharpers have it pretty good, all things considered.

Here's my list:

  • Lambda statements not watchable/evaluatable. Calls to named methods can be plugged into VS's QuickWatch. So can expressions. But lambdas? Nope (at least not in VS2010). Makes debugging Linq chains a real chore.

  • Optional parameter values for reference types other than string can only be null. if I were creating an overload stack, I might want to use other defaults. I might be able to default one value based on a property or simple expression based on another parameter. But I can't. So the value of not having to create an overload stack (which is minor with a refactoring assistant like ReSharper to handle the boilerplate) is diminished when the options for the optional parameters are so drastically limited.

  • C# is becoming old enough to have serious legacy code problems. Code originally written for 1.1 would cause anyone used to 4.0 to cringe in horror. Even 2.0 code misses out on a lot. In the same time, third-party libraries have come in that make things like ADO.NET seem woefully primitive (and much of ADO.NET's "connected model" is now a big anti-pattern). Yet, for backwards-compatibility, .NET schleps along support for all this old, bad code, never daring to say something like "ArrayList was a crappy way to do it, we're sorry we ever put it in and we're taking it out; use List instead and if you absolutely need a list of varying types, declare it as List<Object>.

  • Seriously limited switch statement rules. Probably one of the best things I could say about PowerBuilder is that the Choose Case statement (equivalent to switch) allowed Boolean expressions based on the variable. It also allowed switch statements to fall through even if they had code. I understand the reasons why that second one is disallowed (it's more likely to be done unintentionally than on purpose) but it would still be nice from time to time to write a statement like:

    switch(someInt)
    {
        case < 0: //all negative values enter here
           //...
           break;
        case 0: 
           //...
           break;
        case 1:
           //...
           //no break; continue through to the code for > 1
        case > 1 // all positive values enter here (including 1)
           //...
           break;
    }
    
  • No INumeric interface. If it's a number, you can do math with it. In many cases the actual method doesn't have to care about exactly which types are plugged in; precision is the caller's responsibility. Yet it's not possible to create a generic method or class that can only accept number types as the GTP.
4
  • 3
    "Most C#-savvy candidates who compare it to Java/C/C++ are pretty happy with it". This was my thinking. There's not a lot to hate about C# as it lets you focus on the solution to the business problem rather than the solution to the technical problem. The biggest gripe I have with the language is that I can't use resource strings in switch case tests because they're technically variables and not constants.
    – Stephen
    Sep 11, 2013 at 23:55
  • 4
    The bit on the generics and containers - Useful example with super and obscurity with extends in Generics? explains it a bit. Assigning Bag<Fruit> bag = Bag<Huckleberry> would mean you could do bag.add(new Watermelon()) which couldn't hold it.
    – user40980
    Oct 3, 2013 at 16:47
  • 4
    +1 for the No INumeric. Rare, but annoying.
    – jmoreno
    Oct 4, 2013 at 6:00
  • Suppose Thing<out T> has a static field which is accessed by both an instance method and a static method. If a Thing<Cat> is passed to a method that expects a Thing<Animal>, and that method calls the aforementioned instance and static methods on the Thing<Animal> reference, which static field(s) should those methods access?
    – supercat
    Feb 16, 2014 at 4:55
11

I'd suggest that part of the problem is fear of giving a bad answer -- you say you hate X, interviewer loves X or thinks your reason for hating X is idiotic, saying that you think it's fine may seem the less controversial option.

It's also probably something that most people haven't really given a lot of thought about; they have current problems and past problems, past problems that were caused by the langauge are over with and so people mainly think of the solution and not the problem as that was more significant, and few will have a current problem caused by the language.

7

For an interview I would ask for only 1 or 2, but I agree, if you can't name any limitations of the tool you use, then you probably don't know it very well. We ask this exact question about SSIS and it really helps separate the wheat from the chaff; everyone we have hired who answered this question well turned into a great employee. We need people who have actaul advanced knowledge not someone who has looked at it a couple of times. And I'll bet that is what you want too.

I think it is a valid question and the fact that so many couldn't answer it is just an example of how poor many of the candidates for jobs really are. If someone isn't analytical enough to be able to figure out some limtitations of the tool, how are they ever going to be analytical enought to solve difficult programming problems?

2
  • 1
    +1 Five is intimidating, for this reason 1 or 2 would probably get more answers. Aug 7, 2012 at 2:36
  • 2
    Hate is quite different from a limitation......
    – mattnz
    Aug 7, 2012 at 3:04
4

It comes down to like you said lack of in depth experience with C# and/or lack of exposure to other languages. I've interviewed a number of developers who considered themselves senior who couldn't answer some questions that even a light scratch at the surface of C# should have revealed to them.

Without enough digging, you're not going to reach the limits of the language and wish that they were gone. My top five in case anyone's wondering

  1. Immutable objects require a lot of ceremony to create (as opposed to a functional language where objects are immutable by default).
  2. Metaprogramming is difficult to do. Compare type emit to Lisp macros. (Compiler Services will help a lot with this going forward).
  3. Extension methods are great...extension properties and extension operators (specifically implicit and explicit operators) would be better.
  4. Explicit Casts are resolved at compile time instead of run-time.
  5. No Sequence Matching it's so much cleaner than function overloading.
1
  • I agree with your first two points, but I shudder at the idea of an extension implicit conversion. Sep 12, 2013 at 15:54
3

I think in his round about way he's saying; if you think it is broken you probably don't understand why it is as it is. There may be a hole in your knowledge.

Ironically, interviewers who think they are quoting "the great Joel" by using that as an interview question are probably rather missing the point.

2
  • I'd argue this is not always the case. E.g., Douglas Crockford says in "JavaScript: The Good Parts" that you should avoid certain features of the language, and I don't think he means they are 'too hardcore' to use.
    – K.Steff
    Aug 6, 2012 at 21:15
  • 10
    I think he's saying the opposite--if you think a platform is not broken in any way at all, you don't know it well enough. That is, his point is that it's fine to stick to a single platform as long as you aren't blind to its shortcomings. Aug 6, 2012 at 21:24
3

They might be reluctant to answer because they might be under the impression that if they can list 5 things they hate about a language the interviewer might turn round and say 'Oh, we're looking for C# 'ninjas' and you don't seem to like the language', or 'Why did you apply for the job if you don't like the language?'.

Interviewees are under a lot of pressure to remain positive during interviews.

1
  • if I hate something in a language, that does not mean I hate the language. This question <del>can</del>must be answered in a positive way too. Why do we need HTML5 if we don't hate anything in HTML4? :)
    – e-MEE
    Aug 7, 2012 at 7:47
3

Because languages shape the way we think. By using C# everyday, you have taken the habit of thinking and designing your code in a way that naturally works around the problems of the language.

You now do it without thinking, without even knowing that you do it. This is why it is so difficult to point out what the bad things are. No doubt that the day when you started learning C#, you found a lot of issues, but now you don't see them anymore. Habits are powerful things. Thought habits, even more.

The positive side of this is, if you find it difficult to list the flaws in C#, it must be because you are a good C# programmer, you like the language, and use it more than other languages.

But if you want to become more able to see the flaws in C#, you have to change your way of thinking. Learn more programming languages, and become used to them. Aim for the most different possible languages. You are used to static typing? Try Python or Ruby. You are used to object-oriented and imperative? Haskell is another world entirely.

And when you come back to C#, you will be like, "Why do I need one hundred lines of C# to do this simple thing that's just one line in Haskell?". You will hate a lot of things about C#.

  • C# does not have non-nullable reference types.
  • No algebraic data types.
  • No string interpolation.
  • Syntax is overly verbose everywhere.
  • No macro system.
  • Type inference is limited.
  • No regexp literals.
  • No structural typing.
  • Poor support for immutability.
  • C# structs are error-prone.
  • Standard collections library is very limited.
  • Can't define constraints on parameters of constructors.
  • Can't program generically with constraints on math operators.
  • No 'newtype'.
  • No array slicing, no range literal.
  • Functions do not list the side-effects they can do as part of their type. :)

(Of course no language can have everything. Language design is extremely difficult, and adding every feature into the same language cannot work. Different tools for different purposes.)

Yes, the question is difficult to answer well, especially during an interview. But people that can answer it prove that they have thought about it, that they have some perspective.

1
  • +1. Excellent point. Indeed, many things I actually hate in C# come from the fact that other languages don't have the same drawbacks. The lack of real tuples (i.e. impossibility to do (a, b) = this.something(); like in Python) is the first thing which comes to my mind. Apr 28, 2014 at 21:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.