2011-04-12 15 views
6
public abstract class EventSystemBase<T, K> : IAutoEvent 
    where T : Event 
    where K : IAutoEvent, new() 
{ 
    public static T Instance { get { return EventSystem.Events.OfType<T>().FirstOrDefault(); } } 
    public static IAutoEvent AutoEventInstance { get { return new K(); } } 

    static EventSystemBase() 
    { 
     EventBot.Register(new EventBotEntry(Instance.Name, AutoEventInstance)); 
    } 

    [...] 
} 

Realmente no entiendo cómo se compila.¿Cómo funcionan los constructores estáticos para los tipos genéricos?

  • ¿Cuándo se ejecuta el constructor estático?
  • ¿Por qué puedo usar tipos genéricos en miembros estáticos?
  • ¿Cómo se supone saber qué tipos aplicar?

Respuesta

7
  • El constructor estático es en el primer momento que se necesite. El tiempo exacto es un poco complicado porque si banderas como beforefieldinit en el binario; es probable que no tenga que preocuparse demasiado por los detalles, excepto que se ejecuta cuando se accede al miembro de la primera clase, antes de que sea necesario.

  • Bueno, ¿por qué no? :) Cada tipo del formulario EventSystemBase<T, K> es su propia clase separada y lleva sin relación a las otras instancias genéricas de la clase, por lo que el constructor debe ejecutar para cada uno. Todos son diferentes al tiempo de ejecución en todos los aspectos *.

  • El constructor estático tiene una duración de un tipo "cocido" y no del tipo "en bruto" (es decir, que tiene una duración de la versión con los tipos genéricos sustituidos), así que no hay problema real aquí.

* En realidad, el tiempo de ejecución evita crear instancias duplicadas de genéricos de tipo de referencia. Pero eso no importa aquí, para el programador o para el programa.

0

Si se aplica el mismo conocimiento de mi C++ en su día ...

Los genéricos son generados en tiempo de compilación , y se convierten en muchos separadas y distintas clases. Para cada una de estas clases, el constructor estático se ejecuta antes de que cualquier código haga referencia a la clase estática. El CLR sabe a qué tipos hacer referencia porque cada una de las clases es única.

EventSystemBase < cadena, bytes> no tiene absolutamente ninguna relación con EventSystemBase < cadena, int >. Es como si hubiera escrito dos clases completamente separadas en su código fuente.

class Program 
{ 
    public static void Main() 
    { 
     var myInt = new MyGeneric<int>(); 
     myInt.InstanceMethod(); 
     MyGeneric<int>.StaticMethod(); 

     MyGeneric<long>.StaticMethod(); 
     var myLong = new MyGeneric<long>(); 
     myLong.InstanceMethod(); 

     Console.ReadLine(); 
    } 
} 

public class MyGeneric<T> 
{ 
    static MyGeneric() 
    { 
     Console.WriteLine("Static constructor: {0}", typeof(T).Name); 
    } 

    public static void StaticMethod() 
    { 
     Console.WriteLine("Static method: {0}", typeof(T).Name); 
    } 

    public void InstanceMethod() 
    { 
     Console.WriteLine("Instance method: {0}", typeof(T).Name); 
    } 
} 
+4

¡Los genéricos NO se generan en tiempo de compilación! – Mehrdad

+0

Los genéricos C# funcionan de forma diferente que las plantillas C++ a pesar de una sintaxis similar. –

+0

que no sea el bit de compilación, ¿es correcto? Además, eliminaron mis caretas para anti-xss ... de lo contrario, mi penúltima frase tendría más sentido :( –

2

El constructor estático no es para el tipo genérico abierto. Solo se ejecutará cuando haya especificado los parámetros de tipo, por ejemplo, EventSystemBase<MyEvent, MyAutoEvent>, que en realidad es una clase diferente a, por ejemplo, EventSystemBase<AnotherEvent, MyAutoEvent> con su propio constructor estático . En cada caso, el constructor estático se ejecuta antes de que se cree la primera instancia de esa clase separada o se hace referencia a cualquiera de sus miembros estáticos.

+0

en realidad de lo que estoy a prueba, parece que los miembros estáticos de la clase base Foo son compartidos por Foo Foo y bevacqua

+0

'clase Foo {int public static x = 0;}' 'Foo .x = 10;' 'consola .WriteLine (Foo .x) // todavía cero –

0
  1. El constructor estático en el genérico se invoca cada vez que se invoca una clase genérica T, K> < diferente.

2-3. con 1, debe estar claro, se relata al T, K genérico

Cuestiones relacionadas