[Mono-devel-list] What to do with TypeInitialization in case of exceptions on second attempt to access class ? Singleton pattern

Rafael Teixeira monoman at gmail.com
Mon Oct 25 14:00:39 EDT 2004


Just a comment:

To avoid that behavior, I normally use "lazy initialization" or "on
demand initialization":

class Singleton
{
   Singleton() { throw new ArgumentException("I feel headache. Try
again next night"); }
   private static Singleton instance = null;

   public static Singleton Instance  { 
     get {
       if  (Singleton.instance == null)
           Singleton.instance = new Singleton();
       return Singleton.instance; } 
   }
}

Although it WILL throw an exception in this example, it will do so at
another point in time in code that normally is easier for the class
user to deal with it.

I normally do it more explicit to the class user code:

class Singleton
{
   Singleton() { throw new ArgumentException("I feel headache. Try
again next night"); }
   private static Singleton instance = null;

   public static Singleton Instance  { 
     get {
       if  (Singleton.instance == null)
            try { Singleton.instance = new Singleton(); }  catch
(Exception ex) { log(ex); }
       return Singleton.instance; } 
   }
}

so the user code must be like:

if (Singleton.Instance != null)
   // use Singleton.Instance

All of this doesn't invalidate your report of Mono different behaviour.

Fun,

On Mon, 25 Oct 2004 20:07:10 +0300, Andriy G. Tereshchenko
<mono-list at spam.24.odessa.ua> wrote:
> Hello Mono developers,
> 
> While writing failure tests for one of my projects I've found very tricky issue.
> This is very common to use singleton pattern using static field initiation.
> But in case if your singleton require some access to external objects - like a configuration settings, file, network or database or
> object protected using CRL security - then singleton constructor can fail.
> 
> In this case pattern using static properties fail very-very hard:
> class Singleton
> {
>     Singleton() { throw new ArgumentException("I feel headache. Try again next night"); }
>     public static Singleton Instance  { get {  return Singleton.instance; } }
>     private static Singleton instance = new Singleton();
> }
> 
> First of all - user receive System.TypeInitializationException exceptions.
> This is unexpected to user - but documented feature of CLR.
> But this email not about this. But about future user actions.
> 
> In case if code will try to access this static property at second (third as so on) attempt - here is most funny things happen.
> In Microsoft implementation -  TypeInitialization thrown for all future access.
> This is somethat good - as all users of incorrectly constructed singleton will be notified about this.
> But in the same time - this can result some parts of singleton code executed more that once and result in side-effects.
> 
> In Java - all future access to non-fully constructed classes result in ClassNotFound exception !!  Not good ;-)
> 
> But now then trying to test the same application (Program.cs) on Mono - it looks like Mono decided to implement this in different
> way.
> All future access to property return null and no exceptions ! Not good.
> 
> As for specification - I think this is undocumented.
> CLR Partition I, 8.5.9 Class Type Definition:
> ---
> 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
> ---
> There is nothing about invoking it on second attempt then first attempt failed ;-)
> 
> What do you think ?
> --
> Andriy G. Tereshchenko
> Odessa, Ukraine
> 
> 
> 


-- 
Rafael "Monoman" Teixeira
---------------------------------------
Just the 'crazy' me in a sane world, or would it be the reverse? I dunno...



More information about the Mono-devel-list mailing list