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.
It depends on the context.
For a final class or method, the C# equivalent is sealed.
For a final field, the C# equivalent is readonly.
For a final local variable or method parameter, there's no direct C# equivalent.
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.
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.
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
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.
sealed
Related
I am really confused with the real meaning of the static keyword in C#. I have gone through different articles on internet but none of them are really helping me to understand it's meaning and other sources are not trusted. I know Stack Overflow has some brilliant minds who can help me understand the real meaning of static like
When they get initialized.
static methods, properties, classes and constructors
Static vs readonly vs constant
In short, static effectively means "associated with a type instead of any one instance of the type". So there's one set of static variables for a type (within an AppDomain) whether you have 0 instances or a million; you don't need an instance to access a static member, etc.
The exact point of initialization of static variables depends on whether there's also a static constructor or not, but very broadly speaking it's "once, usually before anything significant happens in the class". (See this blog post for a more detailed description.)
While readonly fields can be either static or instance (i.e. related to the type or related to an instance of the type), const values are always implicitly static (they're compile-time constants, so it wouldn't make sense to have one copy per instance).
You may sometimes see static being described as "shared between all instances of a type" - I personally dislike that description, as it suggests that there has to be at least one instance... whereas actually, you don't need any instances in order to use a static member. I prefer to think of them as entirely separate, rather than being "shared" between instances.
I can recommend this article, it seems pretty descriptive:
Static Keyword Demystified
I would also recommend an official c# Programming Guide article which covers the various uses of the static keyword. You can go from there since there are a lot of links to different MSDN articles.: Static Classes and Static Class Members (C# Programming Guide)
A little about constant (const) and readonly:
constant or const is variable which cannot be modified,and which value is known at compile time.
readonly is very similar to constant, this cannot be modified either, the difference is that a readonly field can be modified/initialized once in the constructor. After that readonly is the same as constant.
Using examples:
constant:
const int a=10; // value cannot be modified, value is known at compile time
But what to do when we want constant field whos value is not known at compile time?
e.g const PersonClass a=new PersonClass("name"); // error
The answer is a readonly field:
readonly:
readonly PersonClass a=new PersonClass("name"); // all correct
From documentation:
The static field variable initializers of a class correspond to a
sequence of assignments that are executed in the textual order in
which they appear in the class declaration
Static members are intializeed on first access to the class and are executed in textual order.
Static methods, properties are parts of the class and not instance.
Static has nothing to do with readonly or constant. Static is a way like a member acessed, readonly and constant is way like a member stored/managed.
I'm trying to wrap my head around Ruby variables and thought it might be good to see them in terms of C#
could someone tell me the C# equivalent of Ruby's (for example is ## == public static variable?):
$ global variable# instance variable## class variable[a-z] local variable[A-Z] constant
any other types of variables I'm missing?
Could someone also explain how #instance variables are used/function?
at first I thought it was some global variable in the instance of a class, but then i saw it used with a scope like a local variable in the instance's method.
here's is an example from the 'well grounded rubyist'
class C
def show_var
#v = "i am an instance variable initialized to a string"
puts #v
end
#v = "instance variables can appear anywhere..."
end
C.new.show_var
if I wanted 'v' to be the same variable from anywhere in the class instance, what is the Ruby mechanism for doing this?
C# does not use sigils for variables.
The "equivalent" C# variable depends entirely on how the variable/member is defined. Note that there are differences even between the "equivalent" forms.
However, there are a number of naming conventions that are encouraged to be followed. The exact conventions used vary by project and may differ from the names I chose below, which reflect my conventions - do not use "class" or "instance" or "local" in real variable names.
Examples:
class MyClass: IMyInterface {
// "const" makes it constant, not the name
public const int CONSTANT = 42;
// static member variable - somewhat like Ruby's ##variable
private static int classVariable;
public static int ExposedClassVariable; // but use properties
// #variable - unlike Ruby, can be accessed outside "self" scope
int instanceVariable;
public int ExposedInstanceVariable; // but use properties
void method (int parameter) {
int localVariable;
}
}
C# does not have "global variables in a shared namespace", but static member variables can be accessed by a stable path which means they can be effectively abused as global variables.
I'm using Visual Studio 2010 + ReSharper and it shows a warning on the following code:
if (rect.Contains(point))
{
...
}
rect is a readonly Rectangle field, and ReSharper shows me this warning:
"Impure Method is called for readonly field of value type."
What are impure methods and why is this warning being shown to me?
First off, Jon, Michael and Jared's answers are essentially correct but I have a few more things I'd like to add to them.
What is meant by an "impure" method?
It is easier to characterize pure methods. A "pure" method has the following characteristics:
Its output is entirely determined by its input; its output does not depend on externalities like the time of day or the bits on your hard disk. Its output does not depend on its history; calling the method with a given argument twice should give the same result.
A pure method produces no observable mutations in the world around it. A pure method may choose to mutate private state for efficiency's sake, but a pure method does not, say, mutate a field of its argument.
For example, Math.Cos is a pure method. Its output depends only on its input, and the input is not changed by the call.
An impure method is a method which is not pure.
What are some of the dangers of passing readonly structs to impure methods?
There are two that come to mind. The first is the one pointed out by Jon, Michael and Jared, and this is the one that ReSharper is warning you about. When you call a method on a struct, we always pass a reference to the variable that is the receiver, in case the method wishes to mutate the variable.
So what if you call such a method on a value, rather than a variable? In that case, we make a temporary variable, copy the value into it, and pass a reference to the variable.
A readonly variable is considered a value, because it cannot be mutated outside the constructor. So we are copying the variable to another variable, and the impure method is possibly mutating the copy, when you intend it to mutate the variable.
That's the danger of passing a readonly struct as a receiver. There is also a danger of passing a struct that contains a readonly field. A struct that contains a readonly field is a common practice, but it is essentially writing a cheque that the type system does not have the funds to cash; the "read-only-ness" of a particular variable is determined by the owner of the storage. An instance of a reference type "owns" its own storage, but an instance of a value type does not!
struct S
{
private readonly int x;
public S(int x) { this.x = x; }
public void Badness(ref S s)
{
Console.WriteLine(this.x);
s = new S(this.x + 1);
// This should be the same, right?
Console.WriteLine(this.x);
}
}
One thinks that this.x is not going to change because x is a readonly field and Badness is not a constructor. But...
S s = new S(1);
s.Badness(ref s);
... clearly demonstrates the falsity of that. this and s refer to the same variable, and that variable is not readonly!
An impure method is one which isn't guaranteed to leave the value as it was.
In .NET 4, you can decorate methods and types with [Pure] to declare them to be pure, and R# will take notice of this. Unfortunately, you can't apply it to someone else's members, and you can't convince R# that a type/member is pure in a .NET 3.5 project as far as I'm aware. (This bites me in Noda Time all the time.)
The idea is that if you're calling a method which mutates a variable, but you call it on a read-only field, it's probably not doing what you want, so R# will warn you about this. For example:
public struct Nasty
{
public int value;
public void SetValue()
{
value = 10;
}
}
class Test
{
static readonly Nasty first;
static Nasty second;
static void Main()
{
first.SetValue();
second.SetValue();
Console.WriteLine(first.value); // 0
Console.WriteLine(second.value); // 10
}
}
This would be a really useful warning if every method which was actually pure was declared that way. Unfortunately they're not, so there are a lot of false positives :(
The short answer is that this is a false positive, and you can safely ignore the warning.
The longer answer is that accessing a read-only value type creates a copy of it, so that any changes to the value made by a method would only affect the copy. ReSharper doesn't realize that Contains is a pure method (meaning it has no side effects). Eric Lippert talks about it here: Mutating Readonly Structs
It sounds like ReSharper believes that the method Contains can mutate the rect value. Because rect is a readonly struct, the C# compiler makes defensive copies of the value to prevent the method from mutating a readonly field. Essentially, the final code looks like this:
Rectangle temp = rect;
if (temp.Contains(point)) {
...
}
ReSharper is warning you here that Contains may mutate rect in a way that would be immediately lost because it happened on a temporary.
An Impure method is a method that could have side-effects. In this case, ReSharper seems to think it could change rect. It probably doesn't but the chain of evidence is broken.
I have a question concerning type constructors within a Value type. This question was inspired by something that Jeffrey Richter wrote in CLR via C# 3rd ed, he says (on page 195 - chapter 8) that you should never actually define a type constructor within a value type as there are times when the CLR will not call it.
So, for example (well...Jeffrey Richters example actually), I can't work out, even by looking at the IL, why the type constructor is not being called in the following code:
internal struct SomeValType
{
static SomeValType()
{
Console.WriteLine("This never gets displayed");
}
public Int32 _x;
}
public sealed class Program
{
static void Main(string[] args)
{
SomeValType[] a = new SomeValType[10];
a[0]._x = 123;
Console.WriteLine(a[0]._x); //Displays 123
}
}
So, applying the following rules for type constructors I just can't see why the value type constructor above is not called at all.
I can define a static value type constructor to set the initial state of the type.
A type can have no more than one constructor - there is no default one.
Type constructors are implicitly private
The JIT compiler checks whether the type's type constructor has already been executed in this AppDomain. If not it emits the call into native code, else it doesn't as it knows the type is already 'initialized'.
So...I just can't work out why I can't see this type array being constructed.
My best guess would be that it could be:
The way that the CLR constructs a type array. I would have thought that the static constructor would be called when the first item was created
The code in the constructor is not initializing any static fields so it is ignored. I have experimented with initializing private static fields within the constructor but the field remains the default 0 value - therefore the constructor is not called.
Or...the compiler is somehow optimizing away the constructor call due to the public Int32 being set - but that is a fuzzy guess at best!!
Best practices etc asside, I am just super intrigued by it as I want to be able to see for myself why it doesn't get called.
EDIT: I added an answer to my own question below, just a quote of what Jeffrey Richter says about it.
If anyone has any ideas then that would be brilliant.
Many thanks,
James
The Microsoft C#4 Spec has changed slightly from previous versions and now more accurately reflects the behaviour that we're seeing here:
11.3.10 Static constructors
Static constructors for structs follow
most of the same rules as for classes.
The execution of a static constructor
for a struct type is triggered by the
first of the following events to occur
within an application domain:
A static member of the struct type is referenced.
An explicitly declared constructor of the struct type is called.
The creation of default values
(§11.3.4) of struct types does not
trigger the static constructor. (An
example of this is the initial value
of elements in an array.)
The ECMA Spec and the Microsoft C#3 Spec both have an extra event in that list: "An instance member of the struct type is referenced". So it looks as if C#3 was in contravention of its own spec here. The C#4 Spec has been brought into closer alignment with the actual behaviour of C#3 and 4.
EDIT...
After further investigation, it appears that pretty much all instance member access except direct field access will trigger the static constructor (at least in the current Microsoft implementations of C#3 and 4).
So the current implementations are more closely correlated with the rules given in the ECMA and C#3 specs than those in the C#4 spec: the C#3 rules are implemented correctly when accessing all instance members except fields; the C#4 rules are only implemented correctly for field access.
(The different specs are all in agreement -- and apparently correctly implemented -- when it comes to the rules relating to static member access and explicitly declared constructors.)
From §18.3.10 of the standard (see also The C# programming language book):
The execution of a static constructor for a struct is triggered by the first of the following events to occur within an application domain:
An instance member of the struct is
referenced.
A static member of
the struct is referenced.
An explicitly declared constructor of the
struct is called.
[Note: The creation
of default values (§18.3.4) of struct
types does not trigger the static
constructor. (An example of this is
the initial value of elements in an
array.) end note]
So I would agree with you that the last two lines of your program should each trigger the first rule.
After testing, the consensus seems to be that it consistently triggers for methods, properties, events, and indexers. That means it's correct for all explicit instance members except fields. So if Microsoft's C# 4 rules were chosen for the standard, that would make their implementation go from mostly right to mostly wrong.
Just putting this in as an 'answer' so that I could share what Mr Richter himself wrote about it (does anyone have a link for the latest CLR spec by the way, its easy to get the 2006 edition but finding it a bit harder to get the latest one):
For this kind of stuff, it is usually better to look at the CLR spec than the C# spec. The CLR spec says:
4. If not marked BeforeFieldInit then that type’s initializer method is executed at (i.e., is triggered by):
• first access to any static field of that type, or
• first invocation of any static method of that type or
• first invocation of any instance or virtual method of that type if it is a value type or
• first invocation of any constructor for that type.
Since none of those conditions are satisfied, the static constructor is not invoked. The only tricky parts to note are that “_x” is an instance field not a static field, and constructing an array of structs does not invoke any instance constructors on the array elements.
Another interesting sample:
struct S
{
public int x;
static S()
{
Console.WriteLine("static S()");
}
public void f() { }
}
static void Main() { new S().f(); }
Update: my observation is that unless static state is used, the static constructor will never be touched - something the runtime seems to decide and doesn't apply to reference types. This begs the question if it's a bug left because it has little impact, it's by design, or it's a pending bug.
Update 2: personally, unless you are doing something funky in the constructor, this behaviour from the runtime should never cause a problem. As soon as you access static state, it behaves correctly.
Update3: further to a comment by LukeH, and referencing Matthew Flaschen's answer, implementing and calling your own constructor in the struct also triggers the static constructor to be called. Meaning that in one out of the three scenarios, the behaviour is not what it says on the tin.
I just added a static property to the type and accessed that static property - it called the static constructor. Without the access of the static property, just creating a new instance of the type, the static constructor wasn't called.
internal struct SomeValType
{
public static int foo = 0;
public int bar;
static SomeValType()
{
Console.WriteLine("This never gets displayed");
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// Doesn't hit static constructor
SomeValType v = new SomeValType();
v.bar = 1;
// Hits static constructor
SomeValType.foo = 3;
}
}
A note in this link specifies that static constructors are not called when simply accessing instances:
http://www.jaggersoft.com/pubs/StructsVsClasses.htm#default
I would guess that you're creating an ARRAY of your value type. So the new keyword would be used to initialize memory for the array.
Its valid to say
SomeValType i;
i._x = 5;
with no new keyword anywhere, which is essentially what you're doing here. Were SomeValType a reference type, you'd have to initialize each element of your array with
array[i] = new SomeRefType();
This is crazy-by-design behavior of "beforefieldinit" attribute in MSIL. It affects C++/CLI too, I filed a bug report where Microsoft very nicely explained why the behavior is the way it is and I pointed out multiple sections in the language standard that didn't agree / need to be updated to describe the actual behavior. But it's not publicly viewable. Anyway, here's the final word on it from Microsoft (discussing a similar situation in C++/CLI):
Since we're invoking the standard
here, the line from Partition I, 8.9.5
says this:
If marked BeforeFieldInit then the
type’s initializer method is executed
at, or sometime before, first access
to any static field defined for that
type.
That section actually goes into detail
about how a language implementation
can choose to prevent the behavior
you're describing. C++/CLI chooses not
to, rather they allow the programmer
to do so if they wish.
Basically, since the code below has
absolutely no static fields, the JIT
is completely correct in simply not
invoking static class constructors.
The same behavior is what you're seeing, although in a different language.
Why does C# not allow const and static on the same line? In Java, you must declare a field as 'static' and 'final' to act as a constant. Why does C# not let you declare const's as final?
I make the further distinction that in Java, every interface is public and abstract, whether this is explicitly declared or not. Aren't const's effectively static in nature? WHy does C# balk at this?
const and static really do mean different things, different storage mechanism, different initialisation. static is read/write, therefore must have memory allocated for storage and must be initialised at runtime. A static can be initialised with a literal value or an expression. In contrast, a const is immutable and must be initialised with a compile time constant (typically a literal value, or an expression that can be fully evaluated at compile time). The value is known at compile time so it can be embedded directly in the generated code, therefore requires no storage to be allocated at runtime.
Constants by their nature are static, so that would be redundant.
As said before, static final in Java is the same as static readonly in C#. In fact, you are saying that this member is static and its content can't be changed. Also you can specify in both cases the value from static constructor.
But const in C# is completely different thing. It's more along the lines of constants in C (DEFINE directives) but with OOP in mind. It's static because it's constant - every instance would have this constant with the same value, no constructor can set it. Also it's possible that someone would like to access the constant without having to create an instance. When you think about it non-static constant just doesn't make sense. You can almost say that constants are not part of an object - they just use it to provide context, a strong name.
Java doesn't have an equivalent to const. You can read somewhere that static final is equivalent to DEFINE but that's just so vague. Completely different mechanism, nothing in common but in the end result in the code is the same - better maintainability and readability of the code.
You just have to stop thinking about constants in C# as static members because they are not. Think of them as OOP version of DEFINE. When you consider encapsulation only reason for final and readonly fields is to prevent your own code from accidently changing its value. And that doesn't sound like constant to me.
Sumary:
final = readonly
static final = static readonly
N/A = const
It is true that a C# const implies static BUT, C# has an equivalent to Java's final keyword in the keyword readonly.
So, in fact, C# allows a const final, it is static readonly in C#.
Because allowing and not requiring modifiers that are inherent can cause confusion. If you see
static const int A = 3
const int B = 5
you may believe that they are 2 different kinds of constants.
Even VB 2008 (which can be very verbose if you wish) doesn't allow that.