473,405 Members | 2,294 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Working of static constructor in case of Generic Types

It seems the static constructor is supposed to be called, ONLY once for a
particular type. If that's the case, why does the following code throws an
exception?

using System;
using System.Collections.Generic;
using System.IO;

namespace GenericTypes
{
class Program
{
static void Main(string[] args)
{

MyList<intlList;
try
{
lList = new MyList<int>();
}
catch
{
}
//Following line throws an error
//should the static constructor, be not called for this instance?
MyList<intlList1 = new MyList<int>();
try
{
MyList<doubleldblList = new MyList<double>();
}
catch
{
}

}

class MyList<T>
{
static int i;
static List<T_myList;
static MyList()
{
_myList = new List<T>();
System.Console.WriteLine("Called for " + typeof(T));
if (!typeof(T).IsEnum)
{
throw new ArgumentException("T must be an enum");
}

}

}
}
}

Mar 28 '07 #1
8 2165
rvmaccount wrote:
It seems the static constructor is supposed to be called, ONLY once for a
particular type. If that's the case, why does the following code throws an
exception?

using System;
using System.Collections.Generic;
using System.IO;

namespace GenericTypes
{
class Program
{
static void Main(string[] args)
{

MyList<intlList;
try
{
lList = new MyList<int>();
}
catch
{
}
//Following line throws an error
//should the static constructor, be not called for this instance?
The static constructor is not called for that instance. If you debug the
code you will see that the static constructor is only entered once.

As the static constructor threw an exception the class is unusable, and
the same exception will be rethrown for every attempt to create an
instance of the class.
MyList<intlList1 = new MyList<int>();
try
{
MyList<doubleldblList = new MyList<double>();
}
catch
{
}

}

class MyList<T>
{
static int i;
static List<T_myList;
static MyList()
{
_myList = new List<T>();
System.Console.WriteLine("Called for " + typeof(T));
if (!typeof(T).IsEnum)
{
throw new ArgumentException("T must be an enum");
}

}

}
}
}
--
Göran Andersson
_____
http://www.guffa.com
Mar 28 '07 #2
The first call of new MyList<intalso throws an exception, but that is
handled by the empty catch-block. Then the class MyList<intis still not
constructed. So the static constructor is also triggered by the second
MyList<int>.

"rvmaccount" <rv********@discussions.microsoft.comschrieb im Newsbeitrag
news:72**********************************@microsof t.com...
It seems the static constructor is supposed to be called, ONLY once for a
particular type. If that's the case, why does the following code throws an
exception?

using System;
using System.Collections.Generic;
using System.IO;

namespace GenericTypes
{
class Program
{
static void Main(string[] args)
{

MyList<intlList;
try
{
lList = new MyList<int>();
}
catch
{
}
//Following line throws an error
//should the static constructor, be not called for this
instance?
MyList<intlList1 = new MyList<int>();
try
{
MyList<doubleldblList = new MyList<double>();
}
catch
{
}

}

class MyList<T>
{
static int i;
static List<T_myList;
static MyList()
{
_myList = new List<T>();
System.Console.WriteLine("Called for " + typeof(T));
if (!typeof(T).IsEnum)
{
throw new ArgumentException("T must be an enum");
}

}

}
}
}

Mar 28 '07 #3
If you debug the code, you will see that the static constructor is only
executed once. Instead the same exception that the static constructor
threw is rethrown when trying to create another instance of the class.

Christof Nordiek wrote:
The first call of new MyList<intalso throws an exception, but that is
handled by the empty catch-block. Then the class MyList<intis still not
constructed. So the static constructor is also triggered by the second
MyList<int>.

"rvmaccount" <rv********@discussions.microsoft.comschrieb im Newsbeitrag
news:72**********************************@microsof t.com...
>It seems the static constructor is supposed to be called, ONLY once for a
particular type. If that's the case, why does the following code throws an
exception?

using System;
using System.Collections.Generic;
using System.IO;

namespace GenericTypes
{
class Program
{
static void Main(string[] args)
{

MyList<intlList;
try
{
lList = new MyList<int>();
}
catch
{
}
//Following line throws an error
//should the static constructor, be not called for this
instance?
MyList<intlList1 = new MyList<int>();
try
{
MyList<doubleldblList = new MyList<double>();
}
catch
{
}

}

class MyList<T>
{
static int i;
static List<T_myList;
static MyList()
{
_myList = new List<T>();
System.Console.WriteLine("Called for " + typeof(T));
if (!typeof(T).IsEnum)
{
throw new ArgumentException("T must be an enum");
}

}

}
}
}
--
Göran Andersson
_____
http://www.guffa.com
Mar 28 '07 #4
On Mar 28, 10:57 am, "Christof Nordiek" <c...@nospam.dewrote:
The first call of new MyList<intalso throws an exception, but that is
handled by the empty catch-block. Then the class MyList<intis still not
constructed. So the static constructor is also triggered by the second
MyList<int>.
No, it's not. The system remembers that the code threw an exception,
and rethrows it. Put a Console.WriteLine in the static constructor -
you'll only see it executed once.

This is not a generics issue, btw. Here's some non-generic code:

using System;

class Broken
{
static Broken()
{
Console.WriteLine ("In static constructor");
throw new Exception("From static constructor");
}

public static void Foo()
{
}
}

class Test
{
static void Main()
{
try
{
Broken.Foo();
}

catch (Exception e)
{
Console.WriteLine(e);
}

try
{
Broken.Foo();
}

catch (Exception e)
{
Console.WriteLine(e);
}
}
}

Jon

Mar 28 '07 #5
What might be the reason for the system to "Remember" the exception. Is it
because, as Goran mentions, that as the class is not usable, so the system
throws the exception?

"Jon Skeet [C# MVP]" wrote:
On Mar 28, 10:57 am, "Christof Nordiek" <c...@nospam.dewrote:
The first call of new MyList<intalso throws an exception, but that is
handled by the empty catch-block. Then the class MyList<intis still not
constructed. So the static constructor is also triggered by the second
MyList<int>.

No, it's not. The system remembers that the code threw an exception,
and rethrows it. Put a Console.WriteLine in the static constructor -
you'll only see it executed once.

This is not a generics issue, btw. Here's some non-generic code:

using System;

class Broken
{
static Broken()
{
Console.WriteLine ("In static constructor");
throw new Exception("From static constructor");
}

public static void Foo()
{
}
}

class Test
{
static void Main()
{
try
{
Broken.Foo();
}

catch (Exception e)
{
Console.WriteLine(e);
}

try
{
Broken.Foo();
}

catch (Exception e)
{
Console.WriteLine(e);
}
}
}

Jon

Mar 28 '07 #6
On Mar 28, 2:08 pm, rvmaccount <rvmacco...@discussions.microsoft.com>
wrote:
What might be the reason for the system to "Remember" the exception. Is it
because, as Goran mentions, that as the class is not usable, so the system
throws the exception?
Exactly. I don't have the CLI spec on hand to check whether it's
documented, but if a type has failed to initialize, it wouldn't be a
good idea to try that initialization repeatedly.

Jon

Mar 28 '07 #7
Jon Skeet [C# MVP] wrote:
On Mar 28, 2:08 pm, rvmaccount <rvmacco...@discussions.microsoft.com>
wrote:
>What might be the reason for the system to "Remember" the exception. Is it
because, as Goran mentions, that as the class is not usable, so the system
throws the exception?

Exactly. I don't have the CLI spec on hand to check whether it's
documented, but if a type has failed to initialize, it wouldn't be a
good idea to try that initialization repeatedly.

Jon
Also, the static constructor is supposed to be executed only once, not
every time there is an attempt to use the class until it succeeds.

Normally a static constructor should never throw an exception. It's not
specified exactly when a static constructor has to be executed, only
that it is executed before anything in the class is used the first time.
Therefore it's impossible to safely catch that exception, as the CLI can
choose to execute the static constructor before the first line of your
main program code.

So, if you have any initialisation that might fail under normal
circumstances, you shouldn't do that in the static constructor.

--
Göran Andersson
_____
http://www.guffa.com
Mar 28 '07 #8
Göran Andersson <gu***@guffa.comwrote:
Also, the static constructor is supposed to be executed only once, not
every time there is an attempt to use the class until it succeeds.

Normally a static constructor should never throw an exception. It's not
specified exactly when a static constructor has to be executed, only
that it is executed before anything in the class is used the first time.
Well, static constructors are specified to execute *immediately* before
the class is used for the first time. Static initializers in a class
without a static constructor are certainly executed in a "looser"
fashion.
Therefore it's impossible to safely catch that exception, as the CLI can
choose to execute the static constructor before the first line of your
main program code.
That depends what the first line of code is :)
So, if you have any initialisation that might fail under normal
circumstances, you shouldn't do that in the static constructor.
Agreed.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 28 '07 #9

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

Similar topics

10
by: Marc Selis | last post by:
Hi, I have a class with a static constructor in which the class registers itself as capable of doing something (using a delegate) The problem is that the static constructor is never called, as...
7
by: Mike P | last post by:
I have a class with a dozen+ properties, some of which will be set a value, and some not, depending on the constructor called. I also have a method which has only one overload and all of the...
15
by: Sharon | last post by:
I’m trying to build a generic Publisher-Subscriber that will work over the net, so I’m using the Remoting. I wish that the subscriber user will be notify about the messages sent by the...
10
by: steve bull | last post by:
I have a class SwatchPanel which takes Swatch as a parameter type. How can I call a static function within the Swatch class? For example the code below fails on TSwatch.Exists. How can I get the...
12
by: Joe Narissi | last post by:
I know how to create and use static constructors, but is there a such thing as a static destructor? If not, then how do you deallocate memory intialized in the static constructor? Thanks in...
12
by: Hemanth | last post by:
Hi, I have a base class with a static constructor and some abstract methods. Derived classes implement these methods. From articles on the web, it appears that there is no guarentee that this...
9
by: Steve Richter | last post by:
in a generic class, can I code the class so that I can call a static method of the generic class T? In the ConvertFrom method of the generic TypeConvert class I want to write, I have a call to...
6
by: =?Utf-8?B?TWF0dA==?= | last post by:
I'm having a problem with a static class constructor being called twice. I have the static class MasterTaskList which uses a BackgroundWorker to execute multiple methods on a separate thread. The...
0
by: SimonDotException | last post by:
I've written an abstract base type which uses generics to provide XML serialization and deserialization methods for use by its derived types, but I'm seemingly unable to write it in a way which...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
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...

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.