What Is the Equivalent of Java's Final in C#

What is the equivalent of Java's final in C#?

The final keyword has several usages in Java. It corresponds to both the sealed and readonly keywords in C#, depending on the context in which it is used.

Classes

To prevent subclassing (inheritance from the defined class):

Java

public final class MyFinalClass {...}

C#

public sealed class MyFinalClass {...}

Methods

Prevent overriding of a virtual method.

Java

public class MyClass
{
public final void myFinalMethod() {...}
}

C#

public class MyClass : MyBaseClass
{
public sealed override void MyFinalMethod() {...}
}

As Joachim Sauer points out, a notable difference between the two languages here is that Java by default marks all non-static methods as virtual, whereas C# marks them as sealed. Hence, you only need to use the sealed keyword in C# if you want to stop further overriding of a method that has been explicitly marked virtual in the base class.

Variables

To only allow a variable to be assigned once:

Java

public final double pi = 3.14; // essentially a constant

C#

public readonly double pi = 3.14; // essentially a constant

As a side note, the effect of the readonly keyword differs from that of the const keyword in that the readonly expression is evaluated at runtime rather than compile-time, hence allowing arbitrary expressions.

C# sealed vs Java final

That's because final in Java means plenty of different things depending on where you use it whereas sealed in C# applies only to classes and inherited virtual members (methods, properties, events).

In Java final can be applied to:

  • classes, which means that the class cannot be inherited. This is the equivalent of C#'s sealed.
  • methods, which means that the method cannot be overridden in a derived class. This is the default in C#, unless you declare a method as virtual and in a derived class this can be prevented for further derived classes with sealed again. That's why you see sealed members in C# a lot less than final members in Java.
  • fields and variables, which means that they can only be initialized once. For fields the equivalent in C# is readonly.

Compared to C#, Java's final is similar to const or readonly

readonly, because just like in C#, you can only set final once, including within the constructor.

C# readonly vs Java final

There is a technical reason for the behavior of readonly: in the created assembly's metadata the field is marked with the initonly attribute that will ensure the field is not modified outside a constructor.1 However, while unverifiable, by taking the address of the readonly field it is still possible to change its value. Verifiable IL and C# will not allow you to do this.

At compile time it is impossible to enforce this for all methods, since the compiler would have to analyze all possible orders in which methods could be called. At runtime it would probably be a burden on the CLR and negative for performance if it had to check every field write whether it has been written to before. Instead, it is safer that C# and the CLR just don't allow the field to be assigned a value anywhere except in the carefully analyzed scope of a constructor.

In my opinion this does not make the readonly keyword any less valuable. I use it all over the place for fields whose value is provided only by the constructor (e.g. creating a list, or storing a constructor argument). C# will ensure that I won't change the field after that ever again, ensuring that I cannot accidentally set it to null or anything.

1) Thanks to Eric Lippert for pointing this out.

What is the c# equivalent of public final static in java

The closest thing (not exactly the same, final has other meanings too) for Java final fields I can think of is readonly:

public static readonly MyClass field = new MyClass("foo");

If you have a primitive type (string, int, boolean), you may want to use const instead.

public const string MAGIC_STRING = "Foo";

Is there any functional difference between c# sealed and Java's final keyword?

Java's final keyword is the equivalent of C#'s sealed, readonly, and sealed keywords.

Two of those three are somewhat different in Java and C#:

In Java, methods are virtual by default, so any method can be declared final to prevent it from being overriden. In C#, methods are not virtual by default, so the only overridden methods can be declared sealed (To prevent them from being further overridden)

In Java, any variable or field can be declared final to prevent it from being changed after initialization (And, for fields, outside the constructor). In C#, fields can be declared readonly, for the exact same effect, but local variables cannot. Note that Java has no equivalent of C#'s const keyword. (consts in C# are evaluated at compile-time, and the values are hard-coded instead of being referenced)

For classes, C#'s sealed classes and Java's final classes are exactly the same (AFAIK).

Understanding Java's final for translation to C#

I think you have a misunderstanding of the final keyword semantic when it is applied to arrays in Java.

In both Java examples the arrays will remain unchanged, but their elements may be changed. All your assignments will be executed correctly, and the values stored in the array will get changed. However, if you try

final int[] PRED = new int[this.Nf];
// some other code
PRED = new int[123]; // <<== Compile error

you are going to see a compile error.

When translating your code to C#, you may need to translate final either as sealed (when it is applied to a class), or as readonly (when it is applied to a member). The semantic of readonly arrays in C# and final arrays in Java are the same: your program cannot reassign the array, but it can freely modify its elements.

Finally, there is a Java-specific case when final is used where you wouldn't need it in C# at all: when you need to use a variable inside a method of an anonymous local class in Java, you must make that variable final. Since C# does not have anonymous local classes, you would need to translate that piece of code with something else, perhaps with anonymous delegates. Such delegates are not restricted to using readonly variables.

Is there an equivalent to Java's :: notation referring to member functions?

In Java, the :: notation is called a method reference. There is no direct equivalent to a method reference in C#, but the closest representation to that in C# is member groups, which allows you to simplify some lambda expressions that meet certain requirements.

This is a good read: https://www.jetbrains.com/help/resharper/ConvertClosureToMethodGroup.html

Without method groups:

    private static int[] ParseInt(string s)
{
var t = ParseString(s);
var i = t.Select(x => int.Parse(x));
return i.ToArray();
}

Using method groups:

    private static int[] ParseInt(string s)
{
var t = ParseString(s);
var i = t.Select(int.Parse);
return i.ToArray();
}

What's the equivalent of the Java operator in C#

It's the right-shift operator, and it's the same in C#.



Related Topics



Leave a reply



Submit