9

In VB you can have this:

Class One
    Private myTwo As Two = New Two(Me)
End Class

Class Two
    Sub New(withOne As One)

    End Sub
End Class

But in C#, you can't do this:

class One
{
    private Two myTwo = new Two(this);
}

class Two
{
    public Two(One withOne)
    {

    }
}

Because you get an error "Keyword 'this' is not available in the current context".

I found this question/answer which quotes the C# language specification section 7.6.7:

7.6.7 This access

A this-access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. ... (specifics omitted) ... Use of this in a primary- expression in a context other than the ones listed above is a compile-time error. In
particular, it is not possible to refer to this in a static method, a static property
accessor, or in a variable-initializer of a field declaration.

Furthermore, this question covers it (although, in my option, does not sufficiently answer it), and Oblivious Sage's answer to my question here explains why -- because it's bug-preventing feature.

Why was this feature left out of VB?

Community
  • 1
  • 1
rory.ap
  • 34,009
  • 10
  • 83
  • 174
  • 1
    This question appears to be off-topic because it is about guessing why the language designer choose to make a particular decision. – Servy Dec 10 '14 at 18:39
  • 4
    @Servy -- Are you just making that reason up? – rory.ap Dec 10 '14 at 18:42
  • 2
    Could be a difference in order of operations when initializing objects. C# doesn't allow it because the `myTwo` initializer will run **before** the `One` being created is a valid object. – Oblivious Sage Dec 10 '14 at 18:42
  • @roryap I used the custom close reason, yes. I could have used "primarily opinion based" instead, and it would apply, but I choose to be more explicit for the sake of clarity. A question in which all anyone can ever do is guess at what someone else is thinking is not on topic here. – Servy Dec 10 '14 at 18:44
  • @Servy -- That assumes that you are correct in saying "all anyone can ever do is guess at what someone else is thinking", which, I believe does not apply here. – rory.ap Dec 10 '14 at 18:45
  • @Servy This doesn't seem like a designer *intent* question. It seems like a "what design features make this work in one .NET language but not another?" question, which should be objectively answerable. – Oblivious Sage Dec 10 '14 at 18:46
  • @roryap So you're assuming that the only people who are ever going to answer this question is the one language designer that made this design decision for C#, and that nobody else is allowed to answer it? – Servy Dec 10 '14 at 18:46
  • As the designers of the C# language, I doubt they would make an arbitrary choice like that and just hide it from posterity. – rory.ap Dec 10 '14 at 18:47
  • @Servy -- No, I'm not assuming that, because I doubt highly that one language designer has the power alone to make such a weighty decision. – rory.ap Dec 10 '14 at 18:48
  • @roryap They make millions of decisions when designing a language. They look over many thousands of features considering which are worth implementing and which aren't. While they may not go out of their way to hide all of the decisions, it's almost certainly not worth their time to go around finding every single question on every single site asking about them to go and answer them. – Servy Dec 10 '14 at 18:48
  • @roryap So the two or three people that might be able to answer it; same difference. Are you honestly expecting one of those very few designers to come to your SO question and answer it for you? – Servy Dec 10 '14 at 18:49
  • 4
    @Servy -- You're thinking about this all wrong. – rory.ap Dec 10 '14 at 18:50
  • @roryap So then you're *not* expecting one of those few MS devs to come an answer your question? If so, how do you expect whomever does answer it to know what they were thinking when they made this decision? Or do you just think that it's not at all unreasonable to expect them to come to your question and answer it? – Servy Dec 10 '14 at 18:51
  • @ObliviousSage -- I disagree that that this is a dupe of that question, as it doesn't actually explain *why*, which is the crux of my question. I think your answer, on the other hand, is perfect. – rory.ap Dec 10 '14 at 19:07
  • The question is certainly a duplicate. You are asking exactly the same thing `Why in C# this is not allowed in member initializer, but in VB.Net Me is allowed` (but more grammatically) Just because it got answers that didn't really answer it very well doesn't make it less so. – Martin Smith Dec 10 '14 at 20:05
  • @MartinSmith -- Just because the title of that other question sounds like the title of my question does not mean they are the same. "Don't judge a book by its cover". And, just because the title of the other question contains the word "Why" and the OP selected an answer doesn't mean the question was answered sufficiently. I'm stipulating that it was *not* answered sufficiently. My question, however, *was* answered sufficiently, which, as the OP, is my prerogative to say. – rory.ap Dec 10 '14 at 20:13
  • Nope. Same question `My question is why is it legal in VB.Net and not C#? Is this down to the compiler handling it differently? It seems weird that the two have different behaviours.` You can put a bounty to attract attention to questions that have already been asked but you feel do not have satisfactory answers. – Martin Smith Dec 10 '14 at 20:16
  • @MartinSmith -- Show me where it discusses the fact that the constructor runs before the field initializers in VB but afterwards in C#? That's the answer, and it's not provided anywhere in the answers to the other question. – rory.ap Dec 10 '14 at 20:18
  • The contents of the answers are irrelevant to whether or not *the question* is a duplicate or not. You asked the same question, got a somewhat better answer but I don't see the need to campaign to get the question unmarked as duplicate when it clearly is. – Martin Smith Dec 10 '14 at 20:20
  • I note that the way the question is phrased "Why would this VB capability be explicitly denied in C#?" makes an unwarranted assumption that the "feature" is the *lack* of enforcement in VB. This assumption is unwarranted. If the question had been phrased "why was this bug-preventing feature of C# not added to VB.NET?" then it becomes a quite different question. C# and VB are similar but different languages with different semantics, different histories and different design criteria. Asking why there is a difference presumes that the difference was deliberately designed in. – Eric Lippert Dec 11 '14 at 18:10
  • @EricLippert -- "why was this bug-preventing feature of C# not added to VB.NET?" That assumes that I knew it was a bug-preventing feature, which I did not (hence my question). It seems like "because it's a bug-preventing feature in C# that was not added to VB" would be a good *answer* to this question, especially if it included the reason why it's a bug-preventing feature in C#. Since I still don't know the answer to that, could you please explain why? – rory.ap Dec 11 '14 at 18:40
  • @EricLippert -- Ahh, I just re-read Oblivious Sage's answer which explains it. – rory.ap Dec 11 '14 at 18:41

1 Answers1

15

As described in this question, the difference is that constructors run before field initializers in VB.NET but after field initializers in C#. Therefore in VB.NET Me is a valid reference when the initializers run, but in C# this is not yet a valid reference when they run.

Per Eric Lippert C# did it that way so that they could guarantee that readonly fields were always initialized before they could be referenced.

I didn't see it explicitly stated anywhere, but if I had to guess they noticed that flaw in VB.NET while C# was still being developed; they then felt that it was a big enough problem to be worth fixing in C# but not a big enough problem to make a breaking (and probably extensive) change to VB.NET.

Community
  • 1
  • 1
Oblivious Sage
  • 3,326
  • 6
  • 37
  • 58
  • Also, congrats on breaking quadruple digits...welcome to the club :) – rory.ap Dec 10 '14 at 19:08
  • Are you sure to not be between the one or two designers of vb.net? :-) – Steve Dec 10 '14 at 19:59
  • 5
    Good answer; to clarify slightly: that readonly fields are initialized before they are referenced is a desirable outcome, but the feature more generally protects against the whole class of errors caused by accessing members of an object before its constructor has run. – Eric Lippert Dec 11 '14 at 18:06