开发者

Why does C# set private variables before the base constructor, while VB.NET does the opposite?

开发者 https://www.devze.com 2023-02-14 12:49 出处:网络
There was a question comparing C# code and VB.NET and the results between the seemingly identical code were entirely different.

There was a question comparing C# code and VB.NET and the results between the seemingly identical code were entirely different. (I wrote a program that allow two classes to "fight". For whatever reason C# always wins. What's wrong with VB.NET?)

The explanation given is that C# will initialize the class fields, then call 开发者_运维知识库the base constructor, but VB.NET does the exact opposite.

My question is - why?

Is there a technical reason for the languages to be different? At first glance, it seems that either approach is equally valid, but I can't fathom why they wouldn't have selected the SAME approach.

EDIT: As 'Jeffrey L Whitledge' has pointed out, VB6 did not have inheritance, so I don't think we can say 'to keep VB.NET and VB6 more closely related'.


It is possible for a base constructor to expose an object to the outside world before derived-class constructors have run. While one should often avoid doing this, there are times when it's necessary. For example, one might have two objects which hold references to each other, and each object might have as a class invariant that the reference to the other object must be valid. Creating such a pair of objects would require having one object's constructor pass the partially-constructed object to the other, or having an object's constructor return before its class invariants were satisfied.

If derived-class field initializers are not run until after the base class constructor has run, and if the base-class constructor exposes the object to the outside world, that would mean that the object would be exposed to the outside world before any derived-class initialization had taken place. The creators of C# didn't like that idea, so they made derived-class initializers run before the base class constructor.

On the other hand, running derived-class initializers before the base-class constructor has a disadvantage: those initializers can't make any reference to the object under construction. There's also no way for them to make use of any arguments that are passed to the constructor. Having an object be partially initialized before control is handed over to the base-class constructor may be nice, but there are some severe limits as to how it can be initialized; it may or may not be possible to have the object in a fully-useful state before the base constructor is run.

The creators of vb.net apparently thought that since running initializers before the base constructor doesn't eliminate the need to deal with partially-constructed objects being exposed to the outside world, and since it precludes the use of some useful techniques, it was better to have the initializers run after the base constructor. This makes it possible for a base-level constructor to expose one of its parameters as a field, and then have the derived-class use the value of that field in the derived-class field initializers.

Arguably, the C# approach allows one to do things the vb.net one does not, but the reverse isn't true (one could implement vb-style field initializers by simply writing to the fields at the start of the constructor). On the other hand, having the declaration and initialization of a field next to each other is cleaner than having declarations in one place and initializations someplace else. Too bad neither language allows one to specify that certain specific field declarations should follow the opposite paradigm from the norm.

0

精彩评论

暂无评论...
验证码 换一张
取 消