473,769 Members | 2,359 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

class constructors in a struct

Hi All,

Why is this code valid? How can the static ctor be used? It doesn't act as
class ctor at all.

struct A
{
static A() { }
}
Nov 15 '05 #1
8 2347
100
Hi Pent,
"Pent" <pent> wrote in message
news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
Why is this code valid?
Yes, it is valid.
How can the static ctor be used?
Static constructors is normally used to initialize static fields for a type.
It is quaranteed to be called before any static filed is accessed. Don't
realy on that the static constructor will be executed when the program
starts, type is instantiaded or a static method is called. The only sure
thing, how I said, is that the static constructor will be executed before a
static filed is accessed.
It doesn't act as class ctor at all.
Depends on what you mean by *class constructor*. CLR and IL Assembler call
*.cctor* (class constructor) the same thing that C# calls *static
constructor*. In this case it works how I already explained.
If for you *class ctor* means instance constructor defined for a class
(reference type) rather than for a struct (value type) then no, it doesn't.
struct A
{
static A() { }
}

If your problem is that you cannot declare parameterless constructor for
structures that's right - you cannot. This is because if you instatiate
value type without using *new* operator CLR doesn't call any constructor and
this may leave your object uninitialized. So C# designers decided not to
allow parameterless constructors for value types. This is good decision as
long as CLR works this way.

HTH
B\rgds
100
Nov 15 '05 #2
The question is: What's the purpose of the following code:

struct A
{
static A() { } //this is not called by CLR.
}

If there is no purpose for the above code, then why is it valid?

"100" <10*@100.com> wrote in message
news:eG******** ******@TK2MSFTN GP09.phx.gbl...
Hi Pent,
"Pent" <pent> wrote in message
news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
Why is this code valid?
Yes, it is valid.
How can the static ctor be used?


Static constructors is normally used to initialize static fields for a

type. It is quaranteed to be called before any static filed is accessed. Don't
realy on that the static constructor will be executed when the program
starts, type is instantiaded or a static method is called. The only sure
thing, how I said, is that the static constructor will be executed before a static filed is accessed.
It doesn't act as class ctor at all.
Depends on what you mean by *class constructor*. CLR and IL Assembler call
*.cctor* (class constructor) the same thing that C# calls *static
constructor*. In this case it works how I already explained.
If for you *class ctor* means instance constructor defined for a class
(reference type) rather than for a struct (value type) then no, it

doesn't.

struct A
{
static A() { }
}

If your problem is that you cannot declare parameterless constructor for
structures that's right - you cannot. This is because if you instatiate
value type without using *new* operator CLR doesn't call any constructor

and this may leave your object uninitialized. So C# designers decided not to
allow parameterless constructors for value types. This is good decision as long as CLR works this way.

HTH
B\rgds
100

Nov 15 '05 #3
100
Pent,

Do you want the compiler to generate an error for each method with empty
body you may have?
Yes, your static constructor is redundant in this case, but it is not an
error neither can lead to errors (as parameterless-instance constructors for
value types). So why should be reported as so.

BTW excution can be slightly different if you have

struct Foo
{
static Bar bar = new Bar();
....... More static methods and fields
}

and

struct Foo
{
static Bar bar = new Bar();
...... More static methods and fields
static Foo(){}
}

Existence of redundant looking construtor in the second declaration may have
impact on the moment when bar field will be created (Bar's constructor will
be called).

B\rgds
100

"Pent" <pent> wrote in message news:e8******** ******@TK2MSFTN GP12.phx.gbl...
The question is: What's the purpose of the following code:

struct A
{
static A() { } //this is not called by CLR.
}

If there is no purpose for the above code, then why is it valid?

"100" <10*@100.com> wrote in message
news:eG******** ******@TK2MSFTN GP09.phx.gbl...
Hi Pent,
"Pent" <pent> wrote in message
news:%2******** ********@TK2MSF TNGP12.phx.gbl. ..
Why is this code valid?
Yes, it is valid.
How can the static ctor be used?


Static constructors is normally used to initialize static fields for a

type.
It is quaranteed to be called before any static filed is accessed. Don't
realy on that the static constructor will be executed when the program
starts, type is instantiaded or a static method is called. The only sure
thing, how I said, is that the static constructor will be executed before a
static filed is accessed.
It doesn't act as class ctor at all.


Depends on what you mean by *class constructor*. CLR and IL Assembler

call *.cctor* (class constructor) the same thing that C# calls *static
constructor*. In this case it works how I already explained.
If for you *class ctor* means instance constructor defined for a class
(reference type) rather than for a struct (value type) then no, it

doesn't.
struct A
{
static A() { }
}

If your problem is that you cannot declare parameterless constructor for
structures that's right - you cannot. This is because if you instatiate
value type without using *new* operator CLR doesn't call any constructor

and
this may leave your object uninitialized. So C# designers decided not to
allow parameterless constructors for value types. This is good decision

as
long as CLR works this way.

HTH
B\rgds
100


Nov 15 '05 #4
100 <10*@100.com> wrote:
How can the static ctor be used?


Static constructors is normally used to initialize static fields for a type.
It is quaranteed to be called before any static filed is accessed. Don't
realy on that the static constructor will be executed when the program
starts, type is instantiaded or a static method is called. The only sure
thing, how I said, is that the static constructor will be executed before a
static filed is accessed.


That's only true for types with the .beforefieldini t flag. For other
types, there are more rigid rules.
It doesn't act as class ctor at all.


Depends on what you mean by *class constructor*. CLR and IL Assembler call
*.cctor* (class constructor) the same thing that C# calls *static
constructor*.


Not quite. It's more usually known as a "type initializer" in the ECMA
spec, although "class constructor" comes up as well - I'm not sure why
they have both versions.

In C#, you end up with a type initializer whenever you have static
fields which have initial values. Unless you have a static constructor
as well, the type is flagged as .beforefieldini t, which means that you
only get the guarantee that the type initializer will be called some
time before the fields get used for the first time. If you have a
static constructor as well, you get more rigidly defined behaviour -
the type initializer is only called when it absolutely has to be, but
before the first call to a static method, access of a static field, or
object construction.

See http://www.pobox.com/~skeet/csharp/beforefieldinit.html for more
explanation.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #5
100
Hi Jon,
100 <10*@100.com> wrote:
How can the static ctor be used?
Static constructors is normally used to initialize static fields for a type.
It is quaranteed to be called before any static filed is accessed. Don't realy on that the static constructor will be executed when the program
starts, type is instantiaded or a static method is called. The only sure
thing, how I said, is that the static constructor will be executed before a static filed is accessed.


That's only true for types with the .beforefieldini t flag. For other
types, there are more rigid rules.


Yes, I know that. We had this discussion before, but as long as the question
wasn't "when the static constructor is called" I decided not to go into
details. I said "the only sure thing... " because this is the point where we
can say for sure that the static constructor has been called regardles of
whether ".beforefieldin it" has been set or not. It doesn't act as class ctor at all.
Depends on what you mean by *class constructor*. CLR and IL Assembler call *.cctor* (class constructor) the same thing that C# calls *static
constructor*.


Not quite. It's more usually known as a "type initializer" in the ECMA
spec, although "class constructor" comes up as well - I'm not sure why
they have both versions.


*.cctor* stands for *class constructor* and I was guessing that this might
be the source of confusion.
Even though ECMA refers to that special method as *type initializer* CLR and
ILAsm uses *.cctor* as a name. Furthermore (how you mentioned) ECMA uses
*class constructor* as well; so, I don't thing that the actual name of this
special method is so important as long as it doesn't lead to
misunderstandin gs.

In C#, you end up with a type initializer whenever you have static
fields which have initial values. Unless you have a static constructor
as well, the type is flagged as .beforefieldini t, which means that you
only get the guarantee that the type initializer will be called some
time before the fields get used for the first time. If you have a
static constructor as well, you get more rigidly defined behaviour -
the type initializer is only called when it absolutely has to be, but
before the first call to a static method, access of a static field, or
object construction.
Actually, if *beforefieldini t* is not specified, calling the type
initializer is triggered by the first call to any static, instance or
virtual method or access any static or instance field. Which means when one
starts using the type.

However C# specs doesn't mention beforefieldinit anywhere; I was palying
arround and I couldn't get c# setting beforefieldinit for the type
initilizer of my test class. Either ILDasm doesn't show that flag or my c#
compiler doesn't use it. The tests, I performed, make me think that my c#
comppiler never sets the flag.
B\rgds
100

See http://www.pobox.com/~skeet/csharp/beforefieldinit.html for more
explanation.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #6
100 <10*@100.com> wrote:
In C#, you end up with a type initializer whenever you have static
fields which have initial values. Unless you have a static constructor
as well, the type is flagged as .beforefieldini t, which means that you
only get the guarantee that the type initializer will be called some
time before the fields get used for the first time. If you have a
static constructor as well, you get more rigidly defined behaviour -
the type initializer is only called when it absolutely has to be, but
before the first call to a static method, access of a static field, or
object construction.
Actually, if *beforefieldini t* is not specified, calling the type
initializer is triggered by the first call to any static, instance or
virtual method or access any static or instance field. Which means when one
starts using the type.


The only way to call a virtual method or use an instance field is to
create an instance though, surely... once an object which is an
instance of a type (even if the type is a base class of the most
specific type of the instance, as it were). (Apologies if this doesn't
make sense - I've only had 45 minutes of sleep in the last 30-odd
hours.)
However C# specs doesn't mention beforefieldinit anywhere; I was palying
arround and I couldn't get c# setting beforefieldinit for the type
initilizer of my test class. Either ILDasm doesn't show that flag or my c#
compiler doesn't use it. The tests, I performed, make me think that my c#
comppiler never sets the flag.


No - it *always* sets the flag if you don't include a static
constructor (at least in VS.NET 2003).

Try this:

using System;

class WithoutStaticCo nstructor
{
}

class WithStaticConst ructor
{
static WithStaticConst ructor()
{
}
}

Compile with:

csc /target:library Filename.cs

Open the dll and just expand the two types - beside the red triangle
WithStaticConst ructor will have
..class private auto ansi
and WithoutStaticCo nstructor will have
..class private auto ansi beforefieldinit

(It works with exes as well.)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7
100

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
100 <10*@100.com> wrote:
In C#, you end up with a type initializer whenever you have static
fields which have initial values. Unless you have a static constructor
as well, the type is flagged as .beforefieldini t, which means that you
only get the guarantee that the type initializer will be called some
time before the fields get used for the first time. If you have a
static constructor as well, you get more rigidly defined behaviour -
the type initializer is only called when it absolutely has to be, but
before the first call to a static method, access of a static field, or
object construction.
Actually, if *beforefieldini t* is not specified, calling the type
initializer is triggered by the first call to any static, instance or
virtual method or access any static or instance field. Which means when one starts using the type.


The only way to call a virtual method or use an instance field is to
create an instance though, surely... once an object which is an
instance of a type (even if the type is a base class of the most
specific type of the instance, as it were). (Apologies if this doesn't
make sense - I've only had 45 minutes of sleep in the last 30-odd
hours.)

Yep, What I said is what can be found in ECMA.
"4. If not marked BeforeFieldInit then that type's initializer method is
executed at (i.e., is triggered by):
* first access to any static or instance field of that type, or
* first invocation of any static, instance or virtual method of that type"

Of course you are right for that an instace or virtual method can be called
only if the object is created. When an isntance of a class is created the
instance constructor is executed and it triggers the class static
constructor, I believe. Structures, though, can be created without instance
constructor to be executed. In this case static constructor is not called
upon creation. But it will be called if an instace method is called.
However C# specs doesn't mention beforefieldinit anywhere; I was palying
arround and I couldn't get c# setting beforefieldinit for the type
initilizer of my test class. Either ILDasm doesn't show that flag or my c# compiler doesn't use it. The tests, I performed, make me think that my c# comppiler never sets the flag.


No - it *always* sets the flag if you don't include a static
constructor (at least in VS.NET 2003).


Yes, you are right. I was so surprised of this my "discovery" so I was
inspecting my test project in the release subfolder until I was compiling in
debug version. ;)
However, the compiler doesn't put the beforefileinit flag C# specs will
still be satisfied.

"If a static constructor (§17.11) exists in the class,
execution of the static field initializers occurs immediately prior to
executing that static constructor. Otherwise,
the static field initializers are executed at an implementation-dependent
time prior to the first use of a static field
of that class."

Without .beforefieldini t everything is ok as well.

B\rgds
100
Nov 15 '05 #8
100 <10*@100.com> wrote:
Yep, What I said is what can be found in ECMA.
"4. If not marked BeforeFieldInit then that type's initializer method is
executed at (i.e., is triggered by):
* first access to any static or instance field of that type, or
* first invocation of any static, instance or virtual method of that type"

Of course you are right for that an instace or virtual method can be called
only if the object is created. When an isntance of a class is created the
instance constructor is executed and it triggers the class static
constructor, I believe. Structures, though, can be created without instance
constructor to be executed. In this case static constructor is not called
upon creation. But it will be called if an instace method is called.
Ah yes - good point.
No - it *always* sets the flag if you don't include a static
constructor (at least in VS.NET 2003).


Yes, you are right. I was so surprised of this my "discovery" so I was
inspecting my test project in the release subfolder until I was compiling in
debug version. ;)


:)
However, the compiler doesn't put the beforefileinit flag C# specs will
still be satisfied.


Yup - but as it does, people get confused :( That included me when
someone was saying a singleton was being created before he expected it
to be. I only found out about beforefieldinit at that stage...

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
5481
by: iceColdFire | last post by:
Hi @all, I am trying to include struct and class objects in a union ,like class A{ int a; A(){} }; struct B {
11
5722
by: Shea Martin | last post by:
I have been programming in C++ for over 4 years. I *think* I knew that a struct could have a constructor but I decided to dig into it a little more today, and found that there is very little difference between a struct and a class in C++. Both have inheritance, access modifiers, etc. The only diff I see is the default access level is public vs. private. I have always just used structs as a minimal class, as that is the way
13
4195
by: Ook | last post by:
I have been told that the only difference between a class and a struct is the default interface - private for class, public for struct. My instructor made this statement: Actually there are only 2 differences between classes and structs: 1) The default interface for a class is private whereas it is publie for a struct. 2) A struct supports array-type initialization syntax in addition to constructors whereas a class requires...
7
2485
by: Hyoung Lee | last post by:
A simple method of simulating a class, such as C++ or UML class, in C would be using the struct construct. Similarly, we use C functions to simulate a methods; e.g., rv method_a (&struct, parm_list); Other methods would be fundamentally similar to this approach. Are there any other approaches that would offer better maintainability and readability? Do you have a better way of accurately simulating OO visibility, inheritance,...
5
8732
by: Chris | last post by:
Hi, I don't get the difference between a struct and a class ! ok, I know that a struct is a value type, the other a reference type, I understand the technical differences between both, but conceptually speaking : when do I define something as 'struct' and when as 'class' ? for example : if I want to represent a 'Time' thing, containing : - data members : hours, mins, secs
23
3859
by: mark.moore | last post by:
I know this has been asked before, but I just can't find the answer in the sea of hits... How do you forward declare a class that is *not* paramaterized, but is based on a template class? Here's what I thought should work, but apparently doesn't: class Foo; void f1(Foo* p)
5
2583
by: ScottM | last post by:
I expect this has been covered somewhere, but I can't find it. Given: class A { public: A() {...does stuff...} }; struct S { A a; };
37
4025
by: JohnGoogle | last post by:
Hi, Newbie question... After a recent article in VSJ I had a go at implementing a Fraction class to aid my understanding of operator overloading. After a previous message someone suggested that I implement it as a struct rather than a class which I did and all worked OK. The simplest declaration for the struct is:
2
1838
by: jordanp | last post by:
Hello, I'm having a little trouble here and I'm hoping that somebody might be able to help me out (win32 console program). First off, I know that I can use class function inside of my struct as a struct object...but my issue that I'm having is that my class function is set up so that it sets 3 variables... Example of my class object (has the getter(), and setter() functions below this, but I won't display that here):
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10210
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10043
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9990
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7406
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6672
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5298
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3956
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3561
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.