Friday, 20 May 2011

Why Java developers hate .NET

I have been struggling with .NET.  Actually, I have been fighting pitched battles with it.

All I want to do is take our existing Java client example code and write an equivalent in C#.  Easy, right?

Trisha's Guide to Converting Java to C#

Turns out writing the actual C# is relatively straightforward.  Putting to one side the question of writing optimal code (these are very basic samples after all), to get the examples to compile and run was a simple process:

1. Find-and-replace the following (only you can't use Ctrl+R like I expect.  Sigh.)

final = readonly (but remove from method params)
System.out.printf = Console.WriteLine
Map = Dictionary
BigDecimal = decimal
Set... oh.  I have no idea.

2. When using callbacks, replace anonymous inner classes with delegates


Java
something.doSomething(new SomethingRequest(),
  new SomethingCallBack()
  {
    public void onSuccess()
    {
      System.out.println("Action successful");
    }
  
    public void onFailure()
    {
      System.err.println("Action failed");
    }
  });

C#
private void foo ()
{
  _something.DoSomething(new SomethingRequest(), 
                         SomethingSuccess, 
                         SomethingFailure);
}

private void SomethingSuccess()
{
  Console.WriteLine("Action successful");
}

private void SomethingFailure()
{
  Console.Error.WriteLine("Action failed");
}

I rather like this pattern actually. You can't really tell in the noddy example above, but the C# code is generally shorter and more reusable.

3. Replace getters and setters with properties


Java
private class MyClass
{
  private BigDecimal myField = new BigDecimal("-1.0");

  public BigDecimal getMyField()
  {
    return myField;
  }

  public void setMyField(BigDecimal instructionId)
  {
    this.myField = myField
  }
}

C#
internal class MyClass
{
  public decimal MyField{ get; set; }
}

What the... where did all my code go??

My Thoughts

I was pleasantly surprised with the language. In general, for what I was doing, the equivalent C# was a lot less code. The fact that the syntax is not wildly different from Java made the transition relatively easy, even if I don't get all the nuances.

I didn't really like the enums - I can see what purpose they serve, but I quite like the way the Java ones are pretty much classes in their own right with properties of their own - it allows you to encapsulate some of your simplest domain objects. But it's a minor point, not a deal-breaker.

The C# capitalisation makes me queasy though. I just can't get my head around it. In Java, if I say:
com.mechanitis.foo.Bar
I know the class is Bar and the rest is the package (or namespace, or whatever). This is more useful when you're using static methods and so forth:
com.mechanitis.foo.Bar.thatThingIWantToDo()

In C#, I know the thing at the end is a method and the thing before that is a class, but it doesn't jump out at me:
Com.Mechanitis.Foo.Bar.ThatThingIWantToDo();

And if you're using a property:
Com.Mechanitis.Foo.Bar.MyProperty;

The whole thing makes me dizzy.

You could argue that all this is redundant with modern tools and IDEs doing all the heavy lifting for you - nice colourisation etc.

Which brings me to The Rant.

Oh My Dear God What Is Wrong With Visual Studio?

C# needs to be a shorter, more succinct language because it takes three billion times longer to do anything in Visual bloody Studio.

I'm coming at this from a Java, IntelliJ point of view, so there's always the possibility it might be lack of familiarity with the tool, rather than the tool itself, which is the problem.  It's a long time since I used VS, and that was back in the 90s when I was doing ASP and COM (shhh, don't tell anyone).

But things shouldn't be this hard.  I was ready to accept, due to my newbie status, the IDE not helping me. I didn't expect it to actively hinder me.

For example: it took hours of my life that I will never get back to discover that you can't simply run a class that has a main method by right-clicking and selecting "run" (note: I'm not even trying Ctrl+F10).  No.  I have to select, at a Solution level, which Projects are runnable.  Then I have to select at the Project level the class with the main method I actually want to run.  Then, it opens up a terminal window and runs it in there, which promptly disappears when the program errors or finishes.  What's wrong with outputting in the output window of the IDE? Is that not what it's for?

Finally I worked out how to run the cursed program (seriously, like that's not the first thing everyone wants to do?  How do people write "Hello World"?).  Now, where are the command line arguments?  Of course, they're at the project properties level too, because each project only has one entry point.  I seriously had to Google that too because I couldn't work it out from the IDE alone.


The next day, my ReSharper licence had expired.  I decided I should attempt to limp on without it, after all hundreds of developers must be surviving with just Visual Studio.  How bad could it be?

Very bad, it turns out.

All those helpful little squiggles I was leaning heavily on to convert my Java to C#?

  • The red to tell you you're utterly wrong.
  • The orange to tell you could be using less code.
  • The blue to remind you to stop thinking in Java and helpfully offer corrected naming.
  • The green to suggest stuff that C# could do differently.

Yeah, all gone.

How do people code like this?  Do they really just do a build to check if it's all wrong or not?

Next, I try to find a class.  I actually have no idea how to do this, because I can't use Ctrl+N.  So I Ctrl

I realise this is a waste of time anyway, because one thing that really annoys me about Visual Studio is that I can't find a way to sync the project tree to the class file I'm looking at.  I can't get it to jump to highlight where I am.  When I'm using IntelliJ, I find this dead useful when I want to see other stuff in the same package.

Less than ten minutes after attempting to use Visual Studio without ReSharper, I've abandoned the fight and tracked down a licence and installed it.

Documentation isn't a standard function of .NET?

What sort of message does this give developers?  Documentation isn't important?

I always thought Javadoc was pretty ugly and clunky. In addition, now our IDEs generate so much, it's frequently meaningless.  But it is generated by standard Java tools, and HTML is a standard format that can be read on pretty much any computer with any operating system.

I could not believe how hard it was to get the XML comments out of the C# into something the user can actually read.  Thank goodness, some enterprising member of the team had already done that for us.  All I needed to do was hack/crowbar the tutorial I'd been working on into the generated documentation, so it ended up in the Windows help files in some fashion.

I know there's a way to get HTML/XML files into the end result using Sandcastle, but hours of Googling only told me it was possible, not how to do it.  I still have no idea what the correct question is to ask to find the solution.

Right now, this is an unsolved mystery.  Our .NET client users will have to read the plain HTML I'm afraid.

In Conclusion

Are we lowly Java developers spoilt with our shiny IDEs?

Or is there such a fundamentally different approach to development for .NET people that all the functionality is there, I just can't find it?

I'm disappointed if I'm honest.  I'm sure the .NET camp used to tout their tools as their superiority.  I ended up feeling sorry for the poor NET people.  Is there anything they can use that isn't Visual Studio?


In Conclusion: Despite the nasty capitalisation I found myself surprisingly taken with C#.  But until they can give me a proper development environment, I won't be tempted by the dark side any time soon.

24 comments:

  1. I mostly agree however your properties aren't quite as nice if you actually want just getters. To use the magic property syntax you have to have both get and set, but if you want immutable objects (a.k.a the LMAX way) you have to declare the field and write the get by hand inside the property, which is all rather annoying as properties are supposed to hide this sort of thing from you.

    Also my other rant is .Net events, I know I Know that java has no equivalent but, they are ~90% of the solution. Great you maintain a collection of listeners for me so I don't need to worry about that. BUT you make me check you have one before I can call it!!! Why!?!? If no one is listening drop it on the floor. By all means let me check so that I can avoid expensive object creation if I want, but don't force it on my...

    VS gets better when you convince it to just use ReSharper key bindings, and then start mapping all the things you expect to work via the keyboard to the actions. The search for action and search for key binding stuff works really well apart from the fact its all in a window which only allows about 3 items in the list too be seen at a time and can't be resized!!!

    ReplyDelete
    Replies
    1. > you have to declare the field and write the get by hand inside the property
      you can use private setter actually:
      public decimal MyField{ get; private set; }
      Thanks

      Delete
  2. Yeah, I admit I cheated with the properties - there were very few that are that small, most needed the full syntax. They were still marginally neater than the Java ones though.

    I didn't know that about the events, I haven't really used them in anger yet. One to watch out for!

    ReplyDelete
  3. @Sam -
    public int Age{ get; private set;}
    is your friend, as is
    public event EventHandler ItHappened = delegate{};
    latter is sinmply the null pattern for events

    Trisha - yes you are porting Java to C# - obviously the IDE is expecting C# idioms not Java ones - we don;t put a main in every class - why on earth would I want every class to be an entrypoint to my application? Its not how you write C# code. I'm not saying Visual Studio is perfect but I write alot of code in C# without Resharper (and a fair amount with). I'm very productive with both. Certainly Resharper helps but it also sometimes moans about things I think are unimportant but makes me look at things that aren't an issue

    VS works on solutions and projects: if you want to run lots of stuff and you want to see the output, use the properties of the solution to run "select project" and then use CTRL-F5 to execute without the debugger attached - console window stays open to show you the results

    Personally I would find it irritating if the output ended up in the IDE as it would mix up with other stuff that I might want output there. I guess that comes down to personal preference and personal back-history

    ReplyDelete
  4. oh also final = readonly for fields but final = sealed for types

    basically - fields "readonly" means it can't be changed after ctor

    "sealed" means you can't inherit from it

    Two different concepts so I'm OK with two different keywords

    ReplyDelete
  5. @Richard

    Thanks for the tip on private set.

    As for the NoOp delegate its a good pattern but it doesn't really alleviate my point, its still 90% of the solution.

    As a team were still trying to figure out what the c# patterns are and quite like c# as a language but maybe its our usage pattern but VS really doesn't seem to help our usage patterns.

    ReplyDelete
  6. @Richard Yes, in most circumstances I agree that you don't need (in fact, probably *shouldn't*) have more than one main method. However in this example, I'm writing sample trading bots - each class is a new bot, each class is a standalone application. Having a brand new Solution for all of them seems slightly like overkill - I simply created a "Samples" project to contain all of them.

    I understand VS works at a solution level, and when I was working on VS projects a long time ago that made sense to me. But now I feel like it's an unnecessary hindrance - a little more flexibility wouldn't hurt if the novice user was protected from it.

    ReplyDelete
    Replies
    1. In C# we use [TestMethod] for your "multi-main" systems.

      Your IDE key-shortcuts are wrong try
      Ctrl+, for finding all versions of overidden functions
      Ctrl+R(efactor),M(ethod) to refactor and move entire peices of code
      /// anywhere to create a DOC file that will ship with your dll.

      Ctrl+F5 to run with no debug, F5 with debug.
      use lambda for your delegates


      something.doSomething( (x,y)=> { //bla },
      (x,y) => { //bla }
      );

      Com.Mechanitis.Foo.Bar.ThatThingIWantToDo(); ?? who writes code like this ? it does make me dizzy, use Using, that's what it's for, Java has it too.

      Set is Tuple

      enums in c# are lighter and mostly used for making code readable, not to enforce logic, hence there non classiness.
      Track changes is hidden in Tools-General-Track Changes
      -there is a bug due to visual studio partially created from win32API and partially from wpf, so you need to change the color of your windows theme to see the tracking - it's an annoying bug but you can d/l SExColor addin that solves it (google it)

      regarding commandline arguments, i agree they could have put that in the class template, but as most windows apps are not run from commandline, this is not such a serious thing.

      you can use [Dependency] and #if Debug #endif to make specific changes for different versions (Release, Debug, other)

      it's different, but its not that different :)

      Delete
  7. I can relate to moving to new environments and IDEs/languages. However it's a natural part of learning (coming to grips) - there aren't always equivalents.

    To get the Project Explorer to sync with the selected tab, there is (or should be) a "Track Active Item" option somewhere hidden in your IDE settings somewhere. I don't have VS2xxx installed at the moment so can't help you locate the menu.

    You might also be interested in some tips I posted a long time ago. Whether or not they still apply is a different matter to the latest IDE.

    ReplyDelete
  8. I recently experienced the switch in the opposite direction. That is, for an Android project I was using Java/Eclipse instead of my typical C#/Visual Studio.

    The funny thing is that I had almost the same reaction as you did going the other way.

    I really liked the language, especially the way it enforces disciplined programming through things like checked exceptions and lack of reference parameter passing.

    Also, like you I hated the IDE. I couldn't get my head around how Java developers could even approach productivity in something like eclipse. It seemed like I was constantly downloading add-ins to make it things that I had gotten used to out of the box with Visual Studio. That's not to say that there aren't things I dislike about VS too, but I still definitely prefer it over Eclipse or NetBeans.

    I guess that as developers we discount the value of home IDE advantage. We spend years learning how to bend these tools to our will and eventually take all that knowledge for granted.

    ReplyDelete
    Replies
    1. Btw, try using dot net new Watch features

      Thread watch, the docking in the watch windows, immediate windows for immediate tests.

      Delete
  9. @JohnFX ah, but I don't like Eclipse either ;) I switched to IntelliJ Idea 2 years back and haven't looked back since.

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete
  11. [Just saw this post hanging off the side of a Disruptor post and had to comment.]

    Like @JohnFx, I made the painful reverse switch (as well as Win2K8 to OS X). I started out with Eclipse then switched to IntelliJ and found its idioms so unintuitive I switched back to Eclipse. All those little things which make C# shorter feel so very verbose in Java. Also the IDE doesn't feel so "integrated" in Java-land. For the most part, VS feels like your whole world when writing C#. In Java, I find more and more am transitioning toward the command line and just using the IDE for my debugger/editor. And holy crap XML-config-hell...

    I think it is often what you've been used to that makes the one "better" over another.

    ReplyDelete
  12. I agree, it's definitely what you're used to. I think it would be really valuable to pair with a C# guy/gal to understand how to work with the IDE, and vice versa. To be honest, I didn't really use my IDE properly (Eclipse at the time) when I joined LMAX, I learnt almost everything by pairing with amazing people who knew what they were doing. They were using shortcuts I had no idea existed, to do things I didn't realise I needed to do.

    ReplyDelete
  13. No one hates .net after all .net is just a fork of Java :) Microsoft use Java all .net developers use java they just call it .net .

    The thing is that usually when you make a Fork you create something AWESOME but in this case they just created a Fork .. with ... a lot of garbage ... and..... properties :) lol great

    Anyway Android is another Fork :) lets see how it will go actually it started pretty AWESOME so I hope google will not distroy it.

    Also one final note. All ideas which was causing the users to go to the .net platform instead of Java platform are now gone. No many languages for .net most of the languages are totally almost unsupported J# is gone no idea what has happened with Iron Ruby and Iron Python but can I really create a Silverlight app in ... Boo ? NOPE. The whole idea about this .net runtime and platform ware just marketing crap on other hand on Java JRUby Groovy an etc are quite quite good and become more and more popular... If you want to make examples about C# .. make them compared to Groovy :).

    I can just say
    .net platform vs Java platform.

    Java platform wins everywhere, more languages, compatibility, performance, cross platform, options, ides, libraries, people !

    C# vs Java as language.
    Who really cares ? I can use Groovy if I want also it is more possible if someone create C# for the JVM than Java for the .net :)

    ReplyDelete
  14. What about differences in the libraries, i.e., JDK vs. .NET framework? The differences between the Java and C# programming languages are trivial. You won't really hate C#/.NET until you begin to write software and assume you can rely on the .NET framework (like you did with the JDK). Unlike the JDK, .NET is a foul, poorly designed afterthought.

    ReplyDelete
  15. About exporting a Javadoc-like document, you were right on Sandcastle, but you should google for "Sandcastle Help File Builder". Which simplifies the process a lot, although not automatically when compiling. Hope it helps!

    ReplyDelete
  16. If you think Java->C# is bad now you should have tried it when it was VS2003 not VS2010. I spent a lot of time sitting in the rain where no one could see the tears... resharper makes things much better, but its not intellij. I still don't understand how anyone uses eclipse.

    ReplyDelete
  17. I liked the first few comments since there are exchanges of ideas, the conversations are very civilized, and participants are open minded. Then suddenly, a fan boy appeared T_T

    ReplyDelete
  18. In terms of having multiple main methods. You wouldn't have more than one per project. You can, however, have multiple projects per solution. So you'd have a project per executable program in your solution.

    Solving running them without having to change the default start up project? right click the project in the solution pane, theres a debug menu item that expands with a "Start New Instance" item. Click that, and you've started that project.

    :) Hope that helps.

    ReplyDelete
  19. When it comes to the IDE, there's a few things that could have made things easier for you.
    First off you should have started from the command line application template project. No need to set anything as runable there, or set the main method. It's all preconfigured in there.

    I'm not using ReSharper and I'm also getting wiggly lines. You are using VS 2010 right?
    I'm not getting the orange ones, but all the other ones are there and helping a lot. There's even a hint if you hoover them with the mouse.
    The hints can also be used to have VS auto-complete stuff, like an interface implementation or a missing class method etc.

    One good and free additional tool to install with VS are the VS Productivity Power Tools. I always found that a funny name, as if you can't be productive without them. I guess there must be a Java developer on that team. ;)

    You should also take some time (a few minutes, not hours) to go through the IDE settings. There are some handy things in there you might like, such as an auto-track item for your solution explorer. It really is in there, but I don't get why that one isn't on by default.

    VS has it quirks no doubt, but as with any tool it takes time to master it. It's especially hard if you're used to a different IDE you know as well as your back pocket. I have the reverse problem with Eclipse really.

    But with VS it's just necessary to release your anger now and then. It comes with the territory.

    ReplyDelete
  20. Thanks everyone for the very useful hints and tips.

    What I think would make my life really easy would be to pair with a C# developer on VS and see how they use it - that's how I really learnt IntelliJ after all.

    ReplyDelete
  21. Hi Trishia
    I felt the same way in a reverse situation, I'm a novice C# developer/hobbyist and I convert existing c# codes to java, and for that, I should change IDEs from VS to eclipse/netbeans.

    I think what turns you OFF when you code in C# is the IDE, not the language itself. When I learned C# years ago, I was not using any IDE,just a plain text editor and compile it with csc. I think you'll know the language better in that way. Now, I am using MonoDevelop most of the time as I always using linux and I want to code in c#-gtk.

    ReplyDelete