Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: bnl en 29 de Agosto de 2007, 11:00:05 PM

Título: Singleton, Static o privada
Publicado por: bnl en 29 de Agosto de 2007, 11:00:05 PM
Buenas

¿La clase GestorGraficos (EngineGrafico) que recubre las Direct3D de DirectX como pensais que debe ser?
- Una clase singleton, accesible por lo tanto desde cualquier punto (simplifica muchas cosas)
- Una clase Static (Shared en VB.NET)
- Uno objeto que se declare a nivel de la clase Juego (la que contiene el bucle principal) como privada
- De otra forma

Yo en principio me inclino por hacerla singleton, pero me gustaria saber vuestra opinión.Quiza se plantearan problemas futuros al ir creciendo el proyecto.

Saludos
Título: Singleton, Static o privada
Publicado por: RobiHm en 29 de Agosto de 2007, 11:45:05 PM
yo singleton forever, si empiezas limitandola...
Título: Singleton, Static o privada
Publicado por: Alexpi en 30 de Agosto de 2007, 01:57:27 AM
ya que estas, siempre he querido saber como son las clases singleton pero no encuentro na.. igual que los tipos de datos Line o algo asi creo que he visto alguna vez. Sabes alguna web que hablen del tema? y si es en español mejor :P :)
Título: Singleton, Static o privada
Publicado por: Pogacha en 30 de Agosto de 2007, 03:04:15 AM
Depende, haciendola singleton podras hacer multiples ventanas?
Mas alla de eso no encuentro otra razón para no hacerlo así.
Título: Singleton, Static o privada
Publicado por: Vicente en 30 de Agosto de 2007, 09:01:45 AM
En Jade la clase principal del engine (Jad) es estática aunque las que recubren DX9 nop.

El único comentario respecto a las clases estáticas es que no inicialices los atributos al declararlos sino en el constructor o vas a tener muuuuuuchos dolores de cabeza.

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: bnl en 30 de Agosto de 2007, 10:56:10 AM
Cita de: "Alexpi"ya que estas, siempre he querido saber como son las clases singleton pero no encuentro na.. igual que los tipos de datos Line o algo asi creo que he visto alguna vez. Sabes alguna web que hablen del tema? y si es en español mejor :P :)

Es el patron mas famoso, hay mucha documentacion en castellano.

Paginas sobre el singleton?
Je,je. Me alegra que me hagas esa pregunta :D

en mi blog hable hace poco del tema y viene el codigo en .NET:
http://www.brausoft.com/2007/07/26/singleton-mas-legible-y-accesible-en-vbnet/
wikipedia: http://es.wikipedia.org/wiki/Singleton_%28patr%C3%B3n_de_dise%C3%B1o%29


El problema que le veo al singleton y a la clase estatica es que si en el futuro (actualmente no se da el caso) necesito por lo que sea varias instancias del gestor no podre tenerlas.


¿Vicente las que recubren a las DX9 como son?
Título: Singleton, Static o privada
Publicado por: StraT en 03 de Septiembre de 2007, 01:09:00 AM
Este es un singleton en c#

using System;

namespace ProyectoDeSingleton
{
  class Singleton
  {
     private static Singleton singleton;
     private Singleton()
     {
        //Aquí lo que sea
     }
     public static Singleton getInstance()
     {
        if(singleton == null)
           singleton = new Singleton();
        return singleton;
     }
  }
}



Saludos!
Título: Singleton, Static o privada
Publicado por: Vicente en 03 de Septiembre de 2007, 07:44:38 AM
Se puede mejorar haciendo la variable singleton readonly e instanciándola en la declaración (instanciación perezosa) y añadiendo un constructor estático vacio (multithreading gratis). Es la forma recomendada de hacer un singleton en C# ;).

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 03 de Septiembre de 2007, 08:35:49 AM
Cita de: "Vicente"Se puede mejorar haciendo la variable singleton readonly e instanciándola en la declaración (instanciación perezosa) y añadiendo un constructor estático vacio (multithreading gratis). Es la forma recomendada de hacer un singleton en C# ;).

Un saludo!

Vicente

Esa implementación ya es perezosa salvo que algo de C# se me escape algo.
Título: Singleton, Static o privada
Publicado por: vincent en 03 de Septiembre de 2007, 08:42:00 AM
Me parece que la buena opción és la de Vicente...

http://en.csharp-online.net/Singleton_design_pattern:_Thread-safe_Singleton
Título: Singleton, Static o privada
Publicado por: Vicente en 03 de Septiembre de 2007, 09:04:25 AM
Cita de: "ethernet"
Cita de: "Vicente"Se puede mejorar haciendo la variable singleton readonly e instanciándola en la declaración (instanciación perezosa) y añadiendo un constructor estático vacio (multithreading gratis). Es la forma recomendada de hacer un singleton en C# ;).

Un saludo!

Vicente

Esa implementación ya es perezosa salvo que algo de C# se me escape algo.

Que con el readonly te ahorras el if ya que readonly te asegura que solo se llama la primera vez :) Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: StraT en 03 de Septiembre de 2007, 02:43:19 PM
Puedes poner mi código modificado de tu forma Vicente? Es que no entiendo a qué te refieres.

Saludos
Título: Singleton, Static o privada
Publicado por: ethernet en 03 de Septiembre de 2007, 02:56:01 PM
Cita de: "Vicente"
Que con el readonly te ahorras el if ya que readonly te asegura que solo se llama la primera vez :) Un saludo!

Vicente

Oh sí, te ahorras un if explícito para ganar uno (o vaya usted a saber) implícito :). Si algo he aprendido es que usar las características del lenguaje para cosas obvias es enmarronar innecesariamente :P java sucks ya de paso.
Título: Singleton, Static o privada
Publicado por: Vicente en 03 de Septiembre de 2007, 03:18:39 PM
Cita de: "StraT"Puedes poner mi código modificado de tu forma Vicente? Es que no entiendo a qué te refieres.

Saludos

El primero que nombran en el link de Vincent es el singleton al que me refería :) Es el ejemplo que vas a encontrar en toooooodos los sitios de como debería ser un singleton en C#.

ethernet: deja de disimular que te encanta java :p Ciertamente no se que se genera por dentro con ese código (esta noche si me acuerdo lo desensamblo). Pero si un lenguaje tiene una característica será para que se use cuando sea necesario, como en este caso ;) No usarla por razones sin fundamento pues en fin...

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 03 de Septiembre de 2007, 04:19:02 PM
Cita de: "Vicente"
Cita de: "StraT"Puedes poner mi código modificado de tu forma Vicente? Es que no entiendo a qué te refieres.

Saludos

El primero que nombran en el link de Vincent es el singleton al que me refería :) Es el ejemplo que vas a encontrar en toooooodos los sitios de como debería ser un singleton en C#.

ethernet: deja de disimular que te encanta java :p Ciertamente no se que se genera por dentro con ese código (esta noche si me acuerdo lo desensamblo). Pero si un lenguaje tiene una característica será para que se use cuando sea necesario, como en este caso ;) No usarla por razones sin fundamento pues en fin...

Un saludo!

Vicente

La razón es que no creo que ganes en tiempo de ejecución y sí en claridad. Habría que ver como funciona el tema del multihread (ya sabemos lo escabroso que son los threads y los singletones).
Título: Singleton, Static o privada
Publicado por: Vicente en 03 de Septiembre de 2007, 04:39:50 PM
Cita de: "ethernet"La razón es que no creo que ganes en tiempo de ejecución y sí en claridad. Habría que ver como funciona el tema del multihread (ya sabemos lo escabroso que son los threads y los singletones).

Lo de que ganas en claridad es relativo. Puedo entender que ganes en claridad para alguien que sea programador de C++ o Java y cuando mire el código C# se diga: y esto del readonly ein? Pero para alguien de C# no se aplica (además que si buscas singleton c# esa es la forma recomendada en toooooooodos los lados).

Y segundo que sin el readonly y poniendo los ifs te toca hacer un lock (el ejemplo 2 del singleton del link que puso Vincent). Y los locks son caros...

No sé, que valor le ves a no hacerlo así además del "artístico" (que ya te digo que me parece discutible por eso, porque es algo de estilo).

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: vincent en 04 de Septiembre de 2007, 09:37:42 PM
Duda que me ha surgido leyendo todo esto: que diferencia hay entre instanciar una variable en la declaración y hacerla en el constructor?

Lo digo también por el comentario de las clases estáticas que ha hecho Vicente...

Gracias!
Título: Singleton, Static o privada
Publicado por: ethernet en 04 de Septiembre de 2007, 09:44:45 PM
dos puntos:

1.- he dicho que prefiero mil veces lo implícito a lo explícito siempre y cuando la funcionalidad sea la misma y el trabajo sea razonablemente el mismo. Si vas a tener que hacer doble lock y usar 50 volatiles es mejor usar lo que te aporte C#

2.- SI quieres leer un buen paper de singleton en un lenguaje para hombres lo mejor es leerte este :
http://erdani.org/publications/DDJ_Jul_Aug_2004_revised.pdf
Título: Singleton, Static o privada
Publicado por: bnl en 04 de Septiembre de 2007, 10:27:30 PM
No conocia esa implementación para C#, es interesante.

Vicente en tu ejemplo no seria instanciacion no perezosa. Por lo que he entendido la variable se instancia al inicio, antes de que se puedan lanzar los hilos. Perezosa seria el ejemplo que puso Strat ¿no?
Título: Singleton, Static o privada
Publicado por: Vicente en 05 de Septiembre de 2007, 12:44:46 PM
Vamos a ver un poco como va la cosa en detalle, el código es este:


public sealed class Singleton
{

  private static readonly Singleton singleton =
     new Singleton();  // eager

  static Singleton() {}

  private Singleton() {}

  public static Singleton GetInstance()
  {
     return singleton;
  }
}


Ahora nos vamos a las especificaciones de C# y tenemos estas cosas:

Citar
ECMA 334, 17.11:
The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

-An instance of the class is created.
-Any of the static members of the class are referenced.

Esto significa que el constructor estático (Type Initializer) es thread-safe porque solo puede ejecutarse 1 vez.

Citar
ECMA 335, 8.9.5:
1- A type may have a type-initializer method, or not.
2- A type may be specified as having a relaxed semantic for its type-initializer method (for convenience below, we call this relaxed semantic BeforeFieldInit)
3- If marked BeforeFieldInit then the type's initializer method is executed at, or sometime before, first access to any static field defined for that type
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
- rst invocation of any static, instance or virtual method of that type

Los tipos que tienen un constructor estático explícito no se marcan como BeforeFieldInit, con lo cual el Type Initializer solo se dispara cuando se accede a una campo estático o de instancia o se invoca un método (el punto 4).

Ahora, si una clase tiene inicializadores en variables estáticas y un constructor estático explícito al ejecutar el Type Initializer se insertan las llamadas a las variables en el orden que están declaradas en la clase al comienzo del constructor (con lo que nuestro new queda protegido por el Type Initializer).

Sin el constructor estático explícito el código podría ser más o menos lazy. Por un lado, sin el constructor el Type Initializer se puede invocar antes de hacer cualquier acceso, con lo cual incluso se podría invocar y que no se use el singleton para nada (en este caso sería más lazy con el constructor porque solo se invoca si se usa).

Pero por otro lado con el constructor estático y el new en la variable si el singleton tuviera más variables o métodos y alguien accediera a ellos se dispararía la construcción del singleton (mientras que si lo metemos en el GetInstance no), con lo cual sería menos lazy (pero con el GetInstance nos toca hacer el lock a nosotros).

Ale, un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: Vicente en 05 de Septiembre de 2007, 02:40:49 PM
Por cierto la MSDN te deja una frase muy buena ethernet :p

Citar
One of the reasons Design Patterns [Gamma95] avoided static initialization is because the C++ specification left some ambiguity around the initialization order of static variables. Fortunately, the .NET Framework resolves this ambiguity through its handling of variable initialization.

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 05 de Septiembre de 2007, 04:31:19 PM
Cita de: "Vicente"Por cierto la MSDN te deja una frase muy buena ethernet :p

Citar
One of the reasons Design Patterns [Gamma95] avoided static initialization is because the C++ specification left some ambiguity around the initialization order of static variables. Fortunately, the .NET Framework resolves this ambiguity through its handling of variable initialization.

Un saludo!

Vicente

Y qué va a decir Microsoft? traducción libre: "hasta ahora teníamos al pobre C++ que está mal definido, menos mal que ha llegado .NET para hacernos ver la luz".

Aparte, como te digo, prefiero tener lo sigueinte:


       SplineManager::manager->Init();
MeshManager::meshManager->Init();
TextureManager::textureManager->Init();
GLTextureManager::manager ->Init();
ShaderManager::shaderManager->Init();
ProgramManager::programManager->Init();
MaterialManager::manager->Init();
CameraManager::manager ->Init();
ObjectManager::objectManager->Init();
PassManager::manager->Init();


que en el fondo son "singletones" y se ve clarísimamente lo que está haciendo y en qué orden lo estás iniciando, sepas C++, C, C#, java o lo que sea a tener 10 ficheros con 10 cosas donde no tienes una visión de lo que pasa en la aplicación o donde necesites saber una característica propia de un lenguaje para ""adivinar"" el funcionamiento.

No es precisamente el uso de singletones lo que hace a la gente dejar de usar C++ para pasarse a otros lenguajes de más alto nivel (lease java, C#, python, etc)
Título: Singleton, Static o privada
Publicado por: Vicente en 05 de Septiembre de 2007, 05:13:28 PM
Cita de: "ethernet"
Y qué va a decir Microsoft? traducción libre: "hasta ahora teníamos al pobre C++ que está mal definido, menos mal que ha llegado .NET para hacernos ver la luz".

Joder que mal pensado eres tio. Yo la frase entiendo de otra forma, más o menos como: "si en C++ la inicialización de variables estáticas estuviera clara el patrón singleton sería como el que hemos hecho en C# en vez de esa cosa con los ifs".

Traduciendo: para el autor usar static es superior a usar ifs, pero no dice que C++ es una basura, simplemente que en C++ no se puede hacer así...

Y yo me pregunto: si en C++ se pudiera hacer con el static (teniendo en cuenta la ventaja que nos da en el tema del lock) ¿tienes alguna razón técnica para elegir los ifs que no sea "me gusta más esta forma de hacerlo porque yo lo veo más claro así"?

(estaría bien que si alguien tiene el libro que citan vea si hablan de esto en el singleton)

Cita de: "ethernet"
Aparte, como te digo, prefiero tener lo sigueinte:


       SplineManager::manager->Init();
MeshManager::meshManager->Init();
TextureManager::textureManager->Init();
GLTextureManager::manager ->Init();
ShaderManager::shaderManager->Init();
ProgramManager::programManager->Init();
MaterialManager::manager->Init();
CameraManager::manager ->Init();
ObjectManager::objectManager->Init();
PassManager::manager->Init();


que en el fondo son "singletones" y se ve clarísimamente lo que está haciendo y en qué orden lo estás iniciando, sepas C++, C, C#, java o lo que sea a tener 10 ficheros con 10 cosas donde no tienes una visión de lo que pasa en la aplicación o donde necesites saber una característica propia de un lenguaje para ""adivinar"" el funcionamiento.

No es precisamente el uso de singletones lo que hace a la gente dejar de usar C++ para pasarse a otros lenguajes de más alto nivel (lease java, C#, python, etc)

Ese método Init es totalmente diferente a lo que estamos hablando en este post. Lo que estábamos viendo es que Tipo.Instancia inicializa el objeto singleton pero que ese proceso internamente se puede hacer de diferentes maneras. Que tu quieres que para inicializar el singleton haya que usar un método llamado Init pues muy bien, pero no aporta nada al tema.

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 05 de Septiembre de 2007, 06:07:39 PM
@vicente: lo de la frase era una coña.

Citar
Ese método Init es totalmente diferente a lo que estamos hablando en este post. Lo que estábamos viendo es que Tipo.Instancia inicializa el objeto singleton pero que ese proceso internamente se puede hacer de diferentes maneras. Que tu quieres que para inicializar el singleton haya que usar un método llamado Init pues muy bien, pero no aporta nada al tema.

Lo que llevo diciendo todo el post: yo no hablo de si C# es muy super chulo por tener 14 formas de iniciar una variable, yo digo que perdiendote en caracterísitcas propias de un lenguaje no ganas nada. De ahí el último ejemplo que hace referencia a la frase de microsoft. Ellos dicen que C++ el control de los contrcutores de los static es ambiguo, bien, pero es que si necesitas control sobre eso no se lo voy a dejar a una caracterísitca del lenguaje, prefiero hacerlo explícito.
Título: Singleton, Static o privada
Publicado por: Vicente en 05 de Septiembre de 2007, 07:31:41 PM
Cita de: "ethernet"@vicente: lo de la frase era una coña.

Mejor que lo aclararas ;)

Cita de: "ethernet"
Lo que llevo diciendo todo el post: yo no hablo de si C# es muy super chulo por tener 14 formas de iniciar una variable, yo digo que perdiendote en caracterísitcas propias de un lenguaje no ganas nada. De ahí el último ejemplo que hace referencia a la frase de microsoft. Ellos dicen que C++ el control de los contrcutores de los static es ambiguo, bien, pero es que si necesitas control sobre eso no se lo voy a dejar a una caracterísitca del lenguaje, prefiero hacerlo explícito.

Ganas un lock respecto a las otras implementaciones clásicas de C# y dos respecto a la de C++ (según me dijiste tú por el IRC, que yo no tengo ni idea de como implementáis singletones en C++).

Esto es muy sencillo: tu escribes el mejor singleton que tu lenguaje es capaz de ofrecerte y yo hago lo mismo. Escribir una cosa peor (porque es peor, ya te digo que cuentes locks) para que la entienda alguien que ni siquiera trabaja con C# es una razón de peso negativo.

Cuando escribes código lo haces basándote en parte en como funciona el lenguaje, en sus normas, sus virtudes y sus defectos. Si C++ no te especifica como funcionan las static pues lógicamente lo especificas tú, pero C# si que lo hace y no entiendo porque tendría que limitarme a la visión del C++ si programo en C# (y porque aplicar semejante "favoritismo" a este caso y no a todos). C# no es un subconjunto ni un superconjunto de C++ y el que se parezcan mucho no me parece razón para justificar la vaguería de no molestarse en aprender como funciona y usarlo lo mejor posible.

Pero vamos, que eso es cosa de gustos. Lo que no es cosa de gustos es que te ahorras los locks y a eso sigues sin responder :p

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 05 de Septiembre de 2007, 11:17:52 PM
Con respecto al tema de los locks: ni puta idea de los locks que hace C# (ya dije hace unos cuantos post que en el tema de threads no entraba). Para implementar un singleton MT en C++ ya puse el paper ese y si lo lees al final te dice que es un putiferio y que pilles la instancia al singleton solo una vez al comienzo del thread para evitar locks innecesarios.

En cualquier caso siendo C# un lenguaje de alto nivel, que en teoría simplica las cosas, no pondría la mano en el fuego por las cosas que hace internamente para dar esa simplicidad. Solo espero que lo haga un poco mejor que java.
Título: Singleton, Static o privada
Publicado por: Vicente en 06 de Septiembre de 2007, 07:45:40 AM
Tio, te he copiado la especificación entera del tema tres posts más arriba, y el resultado es que para ser un singleton MT-safe en C# hacen falta CERO LOCKS :p

Cero patatero y 4 líneas de código, más fácil es complicado hacer las cosas... Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 06 de Septiembre de 2007, 09:59:11 AM
Cita de: "Vicente"Tio, te he copiado la especificación entera del tema tres posts más arriba, y el resultado es que para ser un singleton MT-safe en C# hacen falta CERO LOCKS :p

Cero patatero y 4 líneas de código, más fácil es complicado hacer las cosas... Un saludo!

Vicente

CERO locks Explícitos !!
Título: Singleton, Static o privada
Publicado por: Prompt en 06 de Septiembre de 2007, 10:30:54 AM
Joder como os rayais con los singletons :D hahahaha pobrecito el bnl.

Mirad yo opino que usar el patrón singleton es un hack tipo patron para no hacer algo estatico pero que cumple la misma función.

Yo te digo bnl que no uses ni singleton ni static, si tienes un diseño bueno no te hará falta ningún hack patrón ni nada estático.

Haz un buen diseño. De todas formas, explicame para que quieres que "EngineRender" sea un singleton ? porque yo lo veo inncesario. Que pasaría si quisieras tener 2 viewport con configuraciones diferentes? gestionarias toda esa logica con el singleton engorronandolo al infinito? :)

No hacks señores! No hacks! :P y dejad de discutir y criticar al probre señor singleton! es un tramposo.
Título: Singleton, Static o privada
Publicado por: Vicente en 06 de Septiembre de 2007, 10:34:56 AM
A ver ethernet: si ese lock implícito por la llamada al Type Initializer que comentas existe, existe SIEMPRE, da igual como escriba yo mi singleton o que la clase sea en realidad un singleton o una clase normal y corriente.

Partiendo de que tienes razón y ese lock implícito existe, ¿que gano haciendo yo otro lock más de regalo que no vale para nada? ¿Hacer las cosas mal para quedar bien con los programadores de Java y C++?

Esto es como si en C++ como hay destructores me dedico a llamar yo a mano a los destructores de C#. Pues no: hay un Garbage Collector y en C# se encarga él de destruir los objetos, aunque en C++ las cosas no funcionen igual. Y aquí lo mismo: los inicializadores estáticos son thread-safe y si no lo quieres aprovechar tu mismo, pero no tiene sentido no hacerlo porque otro lenguaje no lo hace...

Un saludo!

Vicente

P.D.: ya te confirmaré si ese lock existe, estoy investigando.
Título: Singleton, Static o privada
Publicado por: Vicente en 06 de Septiembre de 2007, 10:38:07 AM
prompt: a mi la discusión esta me parece interesante, es cierto que se puede vivir sin saber nada sobre memory barriers y demás, pero tampoco está mal saberlo y el que tenga un poco de curiosidad puede haber aprendido bastantes cositas de C# y C++ (yo al menos he aprendido unas cuantas).
Título: Singleton, Static o privada
Publicado por: bnl en 06 de Septiembre de 2007, 11:16:52 AM
Je je. La verdad es que esto ha derivado bastante desde la pregunta inicial.

A mi me ha parecido tambien interesante la discusion. No conocia la forma de hacerlo que ha comentado Vicente. Supongo que en VB.NET se podrá hacer igual que en C#. ¿Alguien lo sabe?

Prompt, a eso venia la duda inicial. Si en un futuro necesitara 2 instancias no valdria el singleton. En principio no veo la necesidad de tener 2 instancias, pero quiza en un futuro si hiciera falta. Por eso he optado por el singleton que era la idea inicial que tenia. Finalmente puse la clase singleton de la forma tradicional ya que no necesito hilos.

Saludos
Título: Singleton, Static o privada
Publicado por: ethernet en 06 de Septiembre de 2007, 12:01:40 PM
Joe Vicente, yo no discuto si en el caso del singleton ganas o pierdes. Es obvio que si para ahcer un singleton tienes que hacer maravillas pero con usando una caracterísitca del lenaguaje lo haces en 30 segundos tomas esta última opción. Pero ante igualdad de condiciones prefiero explícito frente a implícito.
Título: Singleton, Static o privada
Publicado por: Vicente en 06 de Septiembre de 2007, 12:16:29 PM
Pero es que ethernet no son igualdades de condiciones :) Una implementación es mejor que la otra. Y aquí está la respuesta a todas las dudas de este hilo (me lo ha pasado un compañero del curro):

Citar
Extraido de CLR Via C# 2nd edition, por Jeffrey Richter (pag. 189-191):

"
[...]Also, type constructors should always be prívate. C# makes them private for you automatically. In fact, if you explicitly mark a type constructor as private (or anything else) in your source code, the C# compiler issues the following error: 'error CS0515: SomeValType.SomeValType(): access modifiers are not allowed on static constructors.' Type constructors should be private to prevent any developer-written code from calling them; the CLR is always capable of calling a type constructor.

[...]
The calling of a type constructor is a tricky thing. When the JIT compiler is compiling a method, it sees what types are referenced in the code. If any of the types define a type constructor, the JIT compiler checks if the type's type constructor has already been executed for this AppDomain. If the constructor has never been execute, the JIT compiler emits a call to the type constructor into the native code that the JIT compiler is emitting. If the type constructor for the type has already executed, the JIT compiler does not call since it knows that the type is already initialized. (for an example of this, see the 'Type Constructor Performance' section later in this chapter)

[...]
Now after the method has been JIT compiled, the thread starts to execute it and will eventually get to the code that calls the type constructor. In fact, it is possible that multiple threads will be executing the same method concurrently. The CLR wants to ensure that a type's constructor executes only once per AppDomain. To guarantee this, when a type constructor is called, the calling thread acquires a mutually exclusive thread synchronization lock. So if multiple  threads attempt to simultaneously call a type's static constructor, only one thread will acquire the lock and the other threads will block. The first thread will execute the code in the static constructor. After the first thread leaves the constructor, the waiting threads will wake up and will see that the constructor's code has already been executed. These threads will not execute the code again; they will simply return from the constructor method. In addition, if any of these methods ever get called again the CLR knows that the type constructor has already executed and will ensure that the constructor is not called again.

Note: Since the CLR guarantees that a type constructor executes only once per AppDomain and is thread-safe, a type constructor is a great place to initialize any singleton objects required by the type"

Resumiendo: el CLR sí usa un lock la primera vez que se llama al Type Initializer y el Type Initializer es la forma recomendada de inicializar singletons, aunque en otros lenguajes se haga de otra forma (peor pa ellos :p).

Y no me parece que hacer eso sea nada arcano o misterioso, es simplemente conocer el lenguaje con el que trabajas y aprovechar lo que te ofrece.

bnl: en VB.NET es igual. Y la forma tradicional te está costando un if de regalo que no necesitas hacer :p

Un saludo!

Vicente
Título: Singleton, Static o privada
Publicado por: ethernet en 06 de Septiembre de 2007, 01:20:54 PM
Es curioso el sistema. Me gustaría ver la implementación porque de alguna forma tiene que marcar que eso ya esté ejecutado, salvo que se modifique el propio bytecode del método para añadir un RET o lo que sea.