Set<File> s = new HashSet<File>();
s.add( new File( "c:/temp" ) );
s.add( new File( "c:/temp" ) );
System.out.println( s.size() );
This prints 1.The C# code:
ISet<FileInfo> s = new HashSet<FileInfo>();
s.Add( new FileInfo( "c:/temp" ) );
s.Add( new FileInfo( "c:/temp" ) );
Console.WriteLine( s.Count );
This prints 2.They are line-for-line identical. IMO, Java prints the correct result. C# may have reasons for this behaviour, but when you're looking at the code, it's not obvious that two FileInfo objects for the same paths are not equal.
When I wrote KeenWrite[0], I chose Java because of all the reasons you mentioned, plus JavaFX. JavaFX is one of the richest cross-platform GUI libraries available for desktop applications, although it does have quirks.