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

7

638

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

Blackdamp answered 25/8, 2009 at 11:5 Comment(1)
A comment on top of class saying "If you override this class, you are fired!" (off course its a joke :)Alviani
G
946

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.

Grishilde answered 25/8, 2009 at 11:6 Comment(10)
I'd add that all non-static methods in Java are virtual by default. So while in C# you can simply leave out the virtual in the initial definition, you'll need to use "final" to avoid subclasses overriding it in JavaGuilty
good answer - there is one more usage of "final" in java though - on a local variable or method parameter to prevent reassigning it. There is no c# direct equivalent of this.Sackey
readonly member variables can be modified in constructors: pastebin.com/AzqzYGiABarbet
Also note: If you declare a member variable as final in Java, the compiler will complain, if not every constructor assigns a value in every code path, whilst C# only issues a warning in that scenario with a readonly member variablesFranklyn
@Grishilde In the C# example: public class MyClass { public sealed override void MyFinalMethod() {...} } will not compile since there is nothing to override the only way I get this to work is to do something along the lines of: interface IMyClass { void MyFinalMethod(); } public abstract class MyClassSealer : IMyClass { public abstract void MyFinalMethod(); } public class MyClass : MyClassSealer { public sealed override void MyFinalMethod() { } } (Paste this into an IDE) Is there a better way?Anzio
@NickolayKondratyev: Yep, my example was implicit in that you need to be subclassing from another class. You don't need the interface really; that's superfluous, but otherwise that looks about right.Grishilde
-1 "whereas C# marks them as sealed"... this is not correct. C# marks methods non-virtual by default. As you point out, the sealed keyword is only permitted for overridden methods and have a very different meaning than non-virtual. If methods were in fact sealed by default, then method hiding using the new keyword wouldn't make sense.Sterner
@Grishilde "No-one said otherwise". I think the problem is that you failed to mention it entirely. It's an important point in this context, considering that isn't allowed with Java's final (assuming the field isn't being initially defined in the constructor,) which is what you're comparing readonly to. What makes you think it's "common knowledge" when OP didn't even know what the C# equivalent was in the first place?Mcleod
One note: you can mark variables inside methods as final in Java. There is no equivalent in C# - you cannot mark variables inside methods as readonly in C#.Lymph
Since C# 9.0 there is now a final syntax analogue for properties in C# called "init only property", see learn.microsoft.com/de-de/dotnet/csharp/language-reference/…. Allowing it for fields was thought about, but not implemented, see chapter "Allow init as a field modifier" in the linkDisinter
S
219

It depends on the context.

Systemic answered 25/8, 2009 at 11:6 Comment(7)
Actually there is no requirement that a final variable be assigned when it is declared. 'final' means that the variable must be assigned by some code path before it is referenced and no code path allows for the variable to be assigned more than once. This applies to instance variables, which in effect means that constructors must assign the variable explicitly.Approach
+ for For a final local variable or method parameter, there's no direct C# equivalent a huge distinction.Norven
If you are instantiating, const for a local variable can be used. It's not equivalent because of course final lets you separately declare and initialize (and so have different values), but just in case you didn't know...Certifiable
const can only be used on value types. As far as I know there's no way to make an effective constant for a local reference type.Bush
@Bush With strings being the only exception.Revive
Nice, short, not very explanatory though. I tried to make my answer more so.Ultrared
One of the few places where java has something I miss in C#. A final for a local variable to ensure it does not change. "final int someCount = someLinqEnumerable.Count();" would be appreciated. (i'm showing i'm using a method to hydrate the value, thus cannot use const int someCount"Vow
R
53

What everyone here is missing is Java's guarantee of definite assignment for final member variables.

For a class C with final member variable V, every possible execution path through every constructor of C must assign V exactly once - failing to assign V or assigning V two or more times will result in an error.

C#'s readonly keyword has no such guarantee - the compiler is more than happy to leave readonly members unassigned or allow you to assign them multiple times within a constructor.

So, final and readonly (at least with respect to member variables) are definitely not equivalent - final is much more strict.

Rigid answered 7/5, 2010 at 18:45 Comment(0)
U
10

As mentioned, sealed is an equivalent of final for methods and classes.

As for the rest, it is complicated.

  • For static final fields, static readonly is the closest thing possible. It allows you to initialize the static field in a static constructor, which is fairly similar to static initializer in Java. This applies both to constants (primitives and immutable objects) and constant references to mutable objects.

    The const modifier is fairly similar for constants, but you can't set them in a static constructor.

  • On a field that shouldn't be reassigned once it leaves the constructor, readonly can be used. It is not equal though - final requires exactly one assignment even in constructor or initializer.

  • There is no C# equivalent for a final local variable that I know of. If you are wondering why would anyone need it: You can declare a variable prior to an if-else, switch-case or so. By declaring it final, you enforce that it is assigned at most once.

    Java local variables in general are required to be assigned at least once before they are read. Unless the branch jumps out before value read, a final variable is assigned exactly once. All of this is checked compile-time. This requires well behaved code with less margin for an error.

Summed up, C# has no direct equivalent of final. While Java lacks some nice features of C#, it is refreshing for me as mostly a Java programmer to see where C# fails to deliver an equivalent.

Ultrared answered 19/2, 2015 at 9:5 Comment(1)
I remember using the final local variables to disentangle some spaghetti code. When I thought a variable doesn't get overwritten in the method, I just removed the initiation to null, added final. If it compiles, I've just made it more clear. If not, I've learned useful information on where it gets reassigned. Then I can ask the harder questions, like: Is this the intended behavior? And if so, how do I clarify that?Ultrared
B
7

Java class final and method final -> sealed. Java member variable final -> readonly for runtime constant, const for compile time constant.

No equivalent for Local Variable final and method argument final

Ballot answered 25/8, 2009 at 11:20 Comment(0)
P
5

http://en.csharp-online.net/CSharp_FAQ:_What_are_the_differences_between_CSharp_and_Java_constant_declarations

C# constants are declared using the const keyword for compile time constants or the readonly keyword for runtime constants. The semantics of constants is the same in both the C# and Java languages.

Pemmican answered 25/8, 2009 at 11:8 Comment(0)
C
-1

sealed

Croquet answered 25/8, 2009 at 11:7 Comment(1)
That only part of the answer since it depends on the context and adding an explanation and/or examples will make it a lot more digestable for those in need of helpDiablerie

© 2022 - 2024 — McMap. All rights reserved.