Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Field initializer accessing `this`: invalid in C#, valid in Java? [closed]

First, an introduction:

This code:

class C
{
    int i = 5;
    byte[] s = new byte[i];
}

fails to compile with the following error:

A field initializer cannot reference the nonstatic field, method, or property `C.i'

Resharper says something similar: Cannot access non-static field i in static context.

This is inline with what the C# spec says -- that a field initializer can't access the instance currently being created (this) or, by extension, any of the instance fields:

A variable initializer for an instance field cannot reference the instance being created. Thus, it is a compile-time error to reference this in a variable initializer, as it is a compile-time error for a variable initializer to reference any instance member through a simple-name.

However, this works just fine in Java:

class C {
    int i = 5;
    byte s[] = new byte[i]; //no errors here
}

Still with me? Ok, here's the question. Err, questions.

In a hypothetical world where this would be valid in C#, I'm wondering: would it even be possible? If so, what would be the pros and cons that it would add to the table? Also, since it's really supported by Java, do the same pros/cons hold for Java? Or is there a fundamental difference in the way type initializers work in the two languages?

like image 975
Cristian Diaconescu Avatar asked Jun 27 '13 11:06

Cristian Diaconescu


2 Answers

In short, the ability to access the receiver before the constructor body runs is a feature of marginal benefits that makes it easier to write buggy programs. The C# language designers therefore disabled it entirely. If you need to use the receiver then put that logic in the constructor body.

as for why the feature is legal in Java, you'll have to ask a Java designer.

like image 160
Eric Lippert Avatar answered Oct 17 '22 10:10

Eric Lippert


In C#, field initializers are merely convenience semantics for the developer. The compiler moves all field initializers into the body of the constructor ABOVE where the call is made to the base constructor. So fields are initialized going up the ancestor chain, and the class is initialized from the base down.

Static references are ok because they are initialized before anything else.

like image 34
Gayot Fow Avatar answered Oct 17 '22 09:10

Gayot Fow