14 ms·
"Can be tempting to think of it as a Java clone". C# is superior to Java in every way I can think of. Just a couple examples, unsigned types, simple value type
by hossbeast 9y ago
"Can be tempting to think of it as a Java clone".
C# is superior to Java in every way I can think of. Just a couple examples, unsigned types, simple value types without boxing, and a real generics implementation (java generics are truly awful). The reflection API is c# is also far more useful and easy to understand.
- jayd16 9y agoJava enums are better. Seeing as C# is going to run on more than Windows that's about all I can think of.
- Pxtl 9y agoAnonymous inner classes are more powerful than c# anonymous types. I think c# wins out overall, but there are a few corners where Java has features c# is missing, coming from the fact that c# was a bit more pragmatic where Java was a bit more oop-purist in its origins.
- noblethrasher 9y agoAnonymous delegates (which have been available since 2.0) are the equivalent feature in C#, at least as far as use cases go.
- Pxtl 9y agoWhile anonymous inner classes are more verbose, they're also more powerful because you can create a whole class instead of a single method.
- noblethrasher 9y agoBut, they're equivalently powerful with respect to an API. In Java, a method might expect one instance of a class, to which you can pass an instance of anonymous class, whereas in C# a method might expect a set of delegates, to which you can pass a set of anonymous delegates or lambda expressions. However, thanks to C#'s type inference, it actually ends up being far less verbose, yet more flexible, because anonymous delegates and lambdas can close over local variables. So, strictly speaking, they're more powerful than anonymous inner classes. On the other hand, as someone that greatly admires Smalltalk, I sometimes envy Java's slightly better purity.
- pjmlp 9y agoDuring Java early days, I was a big fan of Eclipse's Java browsing perspective, it was a way to feel like I was still using Smalltalk.
- jayd16 9y agoDelegates are nice in the common case but I do miss anonymous classes. Anonymous classes have better oo organization than passing in two or more delegates. Sometimes variable capture doesn't cut it or isn't as clear. ..And the biggest thing. I can pass it in to a method that already takes a class and not a delegate.
- noblethrasher 9y ago> And the biggest thing. I can pass it in to a method that already takes a class and not a delegate. One solution is the build a small inventory of "ad-hoc" classes that just wrap a delegate (usually a closure), as described here: https://stackoverflow.com/questions/20703002/does-object-expression-exist-in-c-sharp-like-in-f/20874683#20874683 https://stackoverflow.com/questions/20703002/does-object-exp...
- tigershark 9y agoWhat are the features that c# is missing? As the other comment explained delegates are the equivalent of anonymous inner classes and are far better. Checked exceptions are really a nuisance, I would call them a negative feature. Java enums in c# are basically classes with readonly properties if you need to pass constructor arguments. Streams in Java are a huge clusterfuck. I can't think to anything that Java has that is better than c#.
- 35bge57dtjku 9y agoIt'd be great if the secret to language design was cramming in as many features as possible.
- int_19h 9y agoDelegates are not the equivalent of anonymous inner classes. They're commonly used for similar design patterns (observer and other callbacks), yes, but they're not the same thing. To be more specific, an anonymous delegate / lambda can be thought of as an implementation of an interface with a single method. But with Java anonymous inner classes, you can implement multiple methods at once. The reasons why Java enums are better, is because they're actually constrained to the domain you specify. In C#, the range of values for any enum is the same as its underlying integer type - it's just that some of those values have names, while others don't. But it's always legal to cast (and few people know this, but 0 is always a valid enum value that you don't need to cast) - so any method you write that accepts an enum value has to validate it. In Java, since enum is basically a final class with a bunch of private singletons, you are guaranteed that the reference you get points to one of those. That said, given that C# now has pattern matching, and it seems to be getting more powerful with every release, I'd be surprised if it didn't get something like case classes very soon.
- noblethrasher 9y agoDelegates and anonymous inner classes are equivalent, modulo API: //Java Bax.addHandler(new Foo() { @Override public void Bar() { doSomething(); } @Override public int Baz(X n) { return computeInt(n); } }); //C# Bax.AddHandler(() => DoSomething(), n => ComputeInt(n)); But, anonymous delegates and lambdas are at once syntactically nicer and more powerful, because of type inference and the fact that they can capture local variables. Regarding Java enums, the actual equivalent feature in C# is class nesting. There is a tiny bit more ceremony involved in defining them, but they're more flexible than Java enums. For instance, you can decide whether or not to implement them as readonly (final) fields, or as static properties, depending on how much you care about cache friendliness. public abstract partial class SomeEnum { private SomeEnum(){} public abstract int Biz(); sealed class AFoo : SomeEnum { public override Biz() => 2 } sealed class ABar : SomeEnum { public override Biz() => 4 } sealed class ABaz : SomeEnum { public override Biz() => 8 } } //Singleton implementation: public abstract partial class SomeEnum { public static readonly SomeEnum Foo = new AFoo(); public static readonly SomeEnum Bar = new ABar(); public static readonly SomeEnum Baz = new ABaz(); } //Cache friendly implementation: public abstract partial class SomeEnum { public SomeEnum Foo => new AFoo(); public SomeEnum Bar => new ABar(); public SomeEnum Baz => new ABaz(); } It's also worth noting that extension methods on C# enums give you most (all?) of the power of Java enums.
- emodendroket 9y ago> The reflection API is c# is also far more useful and easy to understand. It's really annoying that you can't query a Java package to find out what classes it defines.
- sebazzz 9y agoA java package is a namespace right? In .NET you can't query a namespace, but you can query a module (very rarely used) or assembly. Surely Java has something to query a jar.
- emodendroket 9y agoA package is the equivalent of an assembly
- emodendroket 9y agoIf this is technically incorrect, as suggested by the voting, I'd appreciate someone setting me straight.
- jdmichal 9y agoAn assembly is closer to a JAR. It is a single unit which can contain multiple namespaces. However, in the Java runtime, the package is the top-level organizational unit. In .NET, it's the assembly. The fully qualified type name in .NET contains the assembly, namespace, and type name. In Java, it's just the package and type name.
- twic 9y agoThere's nothing built-in quite like that. However, in normal circumstances, you can do it on top of what's in the JDK: pick a class you know is in the jar, load it as a classpath resource URL, parse that URL to find the jar, then read the jar using the built-in jar support. There are other ways to do it, eg starting from the classpath and working down. There are any number of libraries for doing this, eg: https://github.com/lukehutch/fast-classpath-scanner https://github.com/lukehutch/fast-classpath-scanner
- BuckRogers 9y agoAs a language, yes C# is probably better. If I may grant Java a pithy defense as a C# user not as a contradiction but additional information. On the implementation side, Hotspot blows the CLR out of the water on performance. All things being equal that is, not handicapping the Java code, bottlenecks "for realism" and other benchmark-defeating tricks. Java is the superior serverside solution. Other than Hotspot performance, the other big selling point is Java's vastly larger opensource library selection. I like both. I like the fat OOP space. Maintenance reasons is a huge one, I don't want to get burned having to maintain some fly-by-night's code in 10 years from a Frankenstein's creation of random JS libraries. Both Java and C# are industrial-strength designs, with good tooling and a swath of devs. Between the two, I'd still reach for C# myself, because at this point you can have an almost entirely C# codebase from the server to the client. It's good enough in the performance and library aspects that Java holds over its head. I'm expecting the C# package to be quite complete once it adds compiling to wasm to its list. But if I made a career switch, it would be from C# to Java, and nothing else. I admire Rust and (especially) Elixir but no jobs in my area for either of those.
- int_19h 9y agoJava is faster for high-level code. The moment you start using structs and stackalloc and whatnot, Hotspot cannot really keep up. Even for high-level code, it depends on the kind. E.g. Java generic collections have to box value types; I'm not sure if Hotspot even tries to avoid it - I think it does these days - but this kind of analysis is necessarily limited in scope. In C#, value type generics are fully reified, even on JIT level - every combination of type parameters gets its own JIT-compiled implementation.
- pjmlp 9y agoThat is just temporary glitch, until Java gets value types. The biggest problem is that no-one wants to do a Python3 on the pile of Java code written in the last 20 years, so of course that have been doing baby steps, which are starting to see the light now post-Java 9. And they will come, because Java is feeling the pressure on Fintech from companies that want to move away from C++, but still feel some pain, ergo Pony. Java also needs such features for Project Metropolis, the JVM can only be successfully rewritten in Java, if there are no performance regressions. Also, IBM and Azul JVMs do have language extensions for value types.
- _old_dude_ 9y agoI like the irony, you can not say that C# is superior to Java in every way in a discussion about C# Span while Java as ByteBuffer (the same API) since Java 4 (circa 2002 i think).
- benaadams 9y agoSpan<T> out of the box you can use with any type, not just Byte, Char, Double, Float, Int, Long, Short It can be put over an array (as per ByteBuffer); but also over stack allocated memory; a native pointer T* etc The underlying allocation is separate from the type
- _old_dude_ 9y agoByteBuffer provides universal access to on heap/off heap data. JNI or Unsafe allow to create ByteBuffer from native pointers, created in C/C++ or in Java using malloc, memcopy them, etc. This is used (and abused) by most web servers, DataStax or LMAX-Exchange have even created their whole business on that. You also have have CharBuffer, DoubleBuffer, FloatBuffer, etc There is no stack allocated ByteBuffer in Java (Java provides no stack access, this is religious) but in Java can do relaxed data access on Buffer element, volatile access, opaque access, CAS, etc. This is the same API.
- benaadams 9y agoDoes it work over non-primitive and user defined types? Object, InetAddress, etc Though only `struct` value types should be used in stack or native memory due to risk of GC holes
- _old_dude_ 9y agoNo, not yet. I believe there is a prototype of that kind of buffers that comes with the valhalla project (value types) but i've not tested it.
- lysium 9y agoDon't forget tail recursion!