- Genetic
- Reflection
- Static method
In Java, it's impossible to get current class/type in static method. The C# code would be.
// C#
public static Type GetType() {
return MethodBase.GetCurrentMethod().DeclaringType;
}
- Performance
// Java
ArrayList<int> list = new ArrayList<>(); // Compile-time error
In C#, all "primitive" type are actually aliases to ValueType
class under System
namespace.
See Java: int versus Integer and int vs Integer
Java doesn't support covariance and contravariance for generic types.
// Java
List<String> strings = new ArrayList<>();
List<Object> objects = strings; // Compile-time error
// C#
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
// Java
public class Foo {
int x = 0;
public int getX() { return x; }
public void setX(int x) { this.x = x; }
}
// C#
public class Foo {
public int X { get; set; } // Easy, simple, and flexible.
}
// Java
static double x = 1.0;
x = 2.0; // Not thread-safe
See official tutorial.
Change of the method behavior will affect the interface of the class. It requires the caller to be recompiled in order to adapt the new interface. See official tutorial.
// C#
class A {
public int Value { get; set;}
public A(int value) {
Value = value;
}
}
static class Extensions {
public static void Print(this A a) { // Extends A class with Print method.
Console.WriteLine("Value: " + a.Value);
}
}
And magic happens
var a = new A(123);
a.Print(); // Prints "123".
- .NET provides Task Parallel Library which is very powerful and easy-to-use. Unlike most of non-blocking framework which requires you to chain your logic deeply. C# provides await/async syntax to make the code easier to read and write.
- Use Google's cloning to do the deep clone.
Unlike C++ and C#, Java's protected
access modifier acts a little bit unexpected, which also allows classes in the same packages to access it.
Comparison of the access modifiers in both languages:
C# | Java |
---|---|
private | private |
public | public |
internal | protected |
protected | N/A |
internal protected | N/A |
- Which make the code management crazy and inflexible. sometime the filename are too long for some programs to handle.
- Use Joda-time in Java to deal with time-related operations.
// Java
public class Derived extend Base {
public Derived() {
int x = 0; // Compile-time error
super(); // This is enforced by compiler to be the first statement.
}
}
C# has a more clear definition for this:
// C#
public class Derived : Base {
public Derived() : base() {} // Clearer, no chance for error
}
// Java
try (Db db = new Db()) {
db.load();
}
// C#
using (var db = new Db()) {
db.load();
}
- In Java, the declaration of the close-able object must be inside the parentheses.
// Java
Db db;
try (db = new Db()) {} // Compile-time error
It seems that Automatic Resource Management changes the variable scope.
Sometimes when you want a method to pass the parameters by references, ref
and out
come in handy. However, Java lacks of them. Java programmer needs to wrap the variable in an object in order to pass by reference.
// C#
class Program {
public static void Foo(ref int x, out int y, int z)
{
x = Int32.Parse(x.ToString()) + x;
y = Int32.MaxValue;
z = Int32.Parse(z.ToString()) + z;
}
public static void Main()
{
int x = 32, y, z = 32;
Foo(ref x, out y, z);
Console.WriteLine("x = " + x); // 64
Console.WriteLine("y = " + y); // 2147483647 or Int32.MaxValue
Console.WriteLine("z = " + z); // Still 32
}
}
// Java
<T> T get(T x) {
return x;
}
// C#
T Get<T>(T x) {
return default(T); // Returns the default value of generic class T.
}
-
In Java, program could break and continue a labeled loop.
-
In C#, program could goto a label.