Referencia de objeto C# .net no establecida en una instancia de un objeto en clase estática

Tuve un problema extraño después de usar CodeMaid para limpiar mi código. Ahora, la clase que contiene todas mis variables y funciones globales está lanzando excepciones y no puedo entender por qué.

La excepción externa se genera en GlobalClass.GetID(): TypeInitializationException.

La excepción interna es: la referencia de objeto no se establece en una instancia de un objeto

Aquí hay un ejemplo de algún código que está causando esto.

La biblioteca

namespace ErrorCode //Library
{

    public static class GlobalClass
    {
        private static int _globalid = 0; //Never reached
        public static int GlobalID
        {
            get
            {
                return _globalid;
            }
        } //Read-Only

        public static int GetID()
        {
            retun _globalid++; //Crashes here with TypeInitialzationException
        }
    }

    public class Entity
    {
        private int _id;
        public int ID
        {
            get
            {
                return _id;
            }
        }
        public Entity()
        {
            _id = GlobalClass.GetID(); //Crashes here with object reference not set to an instance of an object? 
        }
    }
}

El programa real

using ErrorCode;
namespace MainProgram //The program that will run
{
    public class Program
    {
        public Entity e = new Entity(); //Triggers GlobalClass.GetID()
    }
}

¿Alguna idea?

preguntado el 04 de julio de 12 a las 04:07

La razón globalid no se está alcanzando es porque nunca está creando una instancia de GlobalClass, así que cuando Entity() está tratando de conseguir globalid se estrella. -

@MatthewRz no, GlobalClass es estático. -

@Blorgbeard Hmm, eso es lo que pensé. -

Qué otros ¿Qué inicializadores estáticos tiene en su GlobalClass? -

Este código funciona para mi.. Tal vez perdiste el código incorrecto al simplificarlo para SO -

3 Respuestas

Editó demasiado su código y eliminó la causa real de la excepción. Una clase con un inicializador de campo como este:

public static class Globals {
    private static int _globalid = 0;
}

no es compatible directamente con CLR. El compilador reescribe este código, crea un constructor estático para la clase (o modifica uno existente) y lo escribe así:

public static class Globals {
    private static int _globalid;
    static Globals() {
        _globalid = 0;
    }
}

hace esto por todos las los campos estáticos con un inicializador. Uno de los cuales es lanzar la excepción en su caso, no podemos verlo en su fragmento. Una forma de perseguirlo es obligar al depurador a detenerse en la excepción, Depurar + Excepciones, marcar la casilla de verificación Lanzado para las excepciones CLR.

Respondido 04 Jul 12, 04:07

Gracias voy a darle una oportunidad! ¡Parece que lo arreglaría! - código rojofinal

Intenta usar un constructor estático:

public static class GlobalClass
{
    static GlobalClass()
    {
        GlobalClass._globalid = 0;
    }

    private static int _globalid;
    public static int GlobalID
    {
        get
        {
            return _globalid;
        }
    }

    //...
}

Respondido 04 Jul 12, 04:07

¿No se llamaría nunca a un constructor agregado a una clase estática ya que nunca inicializamos un nuevo objeto fuera de GlobalClass? - código rojofinal

Es un constructor "estático", que se llama "como" un constructor. Pero esto revelará el error si no lo arregla. Nos hemos encontrado con problemas de simultaneidad antes en los que teníamos que especificar explícitamente el constructor estático, en lugar de confiar en que el compilador lo hiciera por nosotros. - lukiffer

Oh, ok, no sabía que las clases estáticas podían tener un constructor, esto simplificará mucho mi código. - código rojofinal

Sospecho, como implica Anthony Pegram, que tiene un constructor estático u otro inicializador de campo estático que no ha incluido en su código de muestra. Este constructor o inicializador lanza la excepción de referencia nula.

Respondido 04 Jul 12, 04:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.