Al parecer, la gran mayoría de los errores en el código son nulas las excepciones de referencia. Hay técnicas generales para evitar encontrar una referencia nula errores?

A menos que me equivoco, soy consciente de que en idiomas como el F# no es posible tener un valor nulo. Pero eso no es la pregunta, me estoy preguntando cómo evitar null errores de referencia en lenguajes como C#.

  • La respuesta es no jugar con null. No calzador como un «código de error», no la coloco sobre como es un objeto real, y de hecho, ni siquiera pensar en la escritura x = null en absoluto, a menos que pueda justificar por qué la vas a usar en este caso en particular. Oh, sí, y si usted está haciendo llamadas a código no de control, consulte la documentación y ver si se puede devolver null demasiado. Y asegúrese de comprobar que si se puede.
  • «la gran mayoría de los errores en el código son nulas las excepciones de referencia» – sólo por curiosidad, ¿de dónde sacaste esa estadística? ¿
  • Escribí «aparentemente» porque se le acaba de decir a mí, yo nunca reclamó para ser una estadística. Fue en una charla por parte de algún empleado de Microsoft que fue hilighting los beneficios de F#.
  • Como un empleado de Microsoft que trabaja en F#, puedo decir definitivamente que no es cierto que «la gran mayoría de los errores en el código son nulas las excepciones de referencia».
  • pues bien, este chico se nos alimenta con algunas de bs hey 🙂
  • (Que dijo, ‘null’ es ‘los mil millones de dólares error’, y muchos idiomas a la fuerza a aceptar ‘null’ como un valor de un tipo de datos, incluso cuando usted no lo quiere. Los errores resultantes de null son normalmente fáciles de identificar, corregir y proteger en contra, pero son insignificantes y están por todas partes, y la ya mencionada ‘mil millones de dólares’ es presumiblemente debido a que el níquel y diming todo el mundo durante las últimas dos décadas.)
  • Casi todos los casos de NullReferenceException son los mismos. Por favor, consulte «¿Qué es una excepción NullReferenceException en .NETA?» para algunos consejos.
  • Tony Hoare introducido referencias Nulas en ALGOL W en 1965 «, simplemente porque era tan fácil de implementar», dice el Señor Hoare. Él habla acerca de que la decisión por considerar que es «mi millones de dólares error» infoq.com/presentations/…

InformationsquelleAutor Nippysaurus | 2009-12-22

15 Comentarios

  1. 30

    Cuando una excepción de referencia nula se muestra al usuario, esto indica un defecto en el código resultante de un error en la parte del desarrollador. Aquí están algunas ideas sobre cómo evitar estos errores.

    Mi recomendación para las personas que se preocupan por la calidad del software, y también el uso de the.net plataforma de programación, es instalar y utilizar el código de Microsoft contratos ( http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx ). Se incluye capacidades para hacer en tiempo de ejecución de la comprobación y verificación estática. La capacidad esencial para la construcción de estos contratos en el código se incluye en la versión 4.0 de the.net marco. Si usted está interesado en la calidad del código, y suena como usted, usted realmente puede disfrutar del uso de código de Microsoft contratos.

    Con el código de Microsoft, contratos, usted puede proteger su método de valores nulos mediante la adición de condiciones previas como este «Contrato.Requiere(cliente != null);». La adición de una condición como ésta es equivalente a la práctica recomendada por muchos otros en sus comentarios anteriores. Antes de contratos de código, le habría recomendado hacer algo como esto

    if (customer == null) {throw new ArgumentNullException("customer");}

    Ahora recomiendo

    Contract.Requires(customer != null);

    A continuación, puede activar el tiempo de ejecución el sistema de comprobación de que la captura de estos defectos tan pronto como sea posible, que conduce hacia el diagnóstico y la corrección de la defectuosa código. Pero no me dejo dar la impresión de que los contratos de código son simplemente una forma elegante de reemplazar argumento null excepciones. Son mucho más poderoso que eso.
    Con el código de Microsoft, contratos, también puede ejecutar la estática corrector, y preguntar a investigar los posibles sitios donde el código de referencia null excepciones pueden ocurrir. La estática corrector requiere un poco más de experiencia para usar fácilmente. No lo recomiendo, la primera para los principiantes. Pero siéntase libre de probar y ver por ti mismo.

    DE INVESTIGACIÓN SOBRE LA PREVALENCIA DE LA REFERENCIA NULA ERRORES

    Ha habido cierto debate en este hilo sobre si la referencia de objeto null errores son un problema significativo. Una respuesta de largo aliento es a continuación. Para las personas que no quieren que vadear a través de eso, voy a resumir.

    • Microsoft los principales investigadores en
      programa de corrección en el número de Especificación y
      código de contratos de proyectos de creer que es
      un problema vale la pena abordar.
    • El Dr. Bertrand Meyer y el equipo de
      los ingenieros de software en ISE, que
      soporte y desarrollo de las Eiffel
      lenguaje de programación, también creen que
      es un problema que vale la pena abordar.
    • En mi propia experiencia en el desarrollo ordinario de software, he visto una referencia nula errores bastante a menudo, que me gustaría abordar el problema en mis propios productos y prácticas.

    Durante años, Microsoft ha invertido en la investigación destinada a mejorar la calidad del software. Uno de sus esfuerzos fue la número de Especificación del proyecto. Una de las novedades más interesantes en mi opinión con the.net 4.0 framework, es la introducción de código de Microsoft contratos, que es una consecuencia de la anterior labor realizada por el número de Especificación del equipo de investigación.

    Con respecto a tu comentario «la gran mayoría de los errores en el código son nulas las excepciones de referencia», creo que es el calificativo de «la gran mayoría» que hará que algunos desacuerdos. La frase «Inmensa mayoría» sugiere que tal vez el 70-90% de los fallos de tener una referencia de objeto null excepción como la raíz de la causa. Este parece ser demasiado alta para mí. Yo prefiero a la cita de la investigación de Microsoft, número de Especificación. En su artículo, El número de Especificación del sistema de programación: Una visión de conjunto, por Mike Barnett, K. Rustan M. Leino, Wolfram y Schulte. En CASSIS DE 2004, LNCS vol. 3362, Springer, 2004, escribieron

    1.0 No Nulo Muchos Tipos de errores en los programas modernos se manifiestan como
    null-eliminar errores, lo que sugiere
    la importancia de una programación
    el lenguaje proporciona la capacidad de
    discriminar entre las expresiones que
    puede evaluar a null y aquellos que
    está seguro de no (para algunos experimental
    prueba, ver [24, 22]). De hecho, nosotros
    quisiera erradicar todas null
    eliminar errores.

    Esta es una fuente probable de la gente de Microsoft que están familiarizados con esta investigación. Este artículo está disponible en el número de Especificación del sitio.

    He copiado las referencias 22 y 24 de abajo, y se incluye el ISBN para su conveniencia.

    • Manuel Fahndrich y K. Rustan M. Leino. La declaración y comprobación de la no-tipos nulos en un
      lenguaje orientado a objetos. En Actas del 2003 ACM Conferencia Orientada a Objetos
      Programación, Sistemas, Lenguajes y Aplicaciones, OOPSLA 2003, volumen 38, número de
      11 en SIGPLAN Avisos, páginas 302-312. ACM, noviembre de 2003. isbn = {1-58113-712-5},

    • Cormac Flanagan, K. Rustan M. Leino, Marca Lillibridge, Greg Nelson, James B. Saxe,
      y Raymie de Stata. Extendido estática comprobación de Java. En Actas del 2002 ACM
      SIGPLAN Conferencia sobre Diseño de lenguajes de Programación y de Ejecución (PLDI), volumen
      37, número 5 en el SIGPLAN Avisos, páginas 234-245. ACM, de Mayo de 2002.

    He revisado estas referencias. La primera referencia que se indica que algunos de los experimentos que hicieron la revisión de su propio código para que sea posible null defectos de referencia. No sólo no encontraron varios, pero en muchos casos, la identificación de un potencial de referencia null indica un problema más amplio con el diseño.

    La segunda referencia no proporciona ninguna evidencia específica de la afirmación de que la referencia de objeto null errores son problema. Pero los autores de estado que en su experiencia, estos null referencia los errores son fuente significativa de los defectos de software. El papel, a continuación, procede a explicar cómo se intenta erradicar estos defectos.

    Yo también recordaba haber visto algo sobre esto en un anuncio de ISE en una reciente publicación de Eiffel. Se refieren a este problema como «vacío de seguridad», y como tantas cosas, inspirado o desarrollado por el Dr. Bertrand Meyer, tienen un elocuente y educativa descripción del problema y cómo ir sobre la prevención en su idioma y herramientas. Les recomiendo leer su artículo http://doc.eiffel.com/book/method/void-safety-background-definition-and-tools para aprender más.

    Si usted desea aprender más acerca de Microsoft código de contratos, hay un montón de artículos que han surgido recientemente. También se puede comprobar en mi blog http: SLASH SLASH codecontracts.info que principalmente está dedicado a las conversaciones acerca de la calidad del software a través del uso de la programación con los contratos.

  2. 21

    Además de lo anterior (Objetos Nulos, Vacío Colecciones), hay algunas técnicas generales, a saber, la Adquisición de Recurso es de Inicialización (RAII) de C++ y Diseño Por Contrato de Eiffel. Estos se reducen a:

    1. Inicializar las variables con valores válidos.
    2. Si una variable puede ser nulo, luego comprobar el valor null y tratarlo como un caso especial o esperar una excepción de referencia null (y lidiar con eso). Afirmaciones puede ser utilizado para la prueba de contrato de violaciones en las versiones en desarrollo.

    He visto un montón de código que se parece a esto:

    if ((valor != null) && (valor.getProperty() != null) && … && (…doSomethingUseful())

    Un montón de tiempo, esto es completamente innecesario y la mayoría de las pruebas podría ser eliminado con estrictos de inicialización y al endurecimiento de las definiciones de contrato.

    Si esto es un problema en su base de código, a continuación, es necesario entender en cada caso cuál es el valor nulo representa:

    1. Si el valor nulo representa una colección vacía, utilice una colección vacía.
    2. Si el valor nulo representa un caso excepcional, lanzar una Excepción.
    3. Si el valor nulo representa un accidentalmente sin inicializar valor, en la que explícitamente se inicializa.
    4. Si el valor nulo representa un valor legítima, la prueba para él – o mejor aún utilizar un NullObject que realiza un null op.

    En la práctica, esta norma de la claridad en el nivel de diseño no es trivial y requiere de esfuerzo y la auto-disciplina para aplicar de forma coherente a su base de código.

  3. 7

    No.

    O más bien, no hay nada especial que hacer para tratar de impedir NREs en C#. La mayor parte de un NRE es sólo algún tipo de error de lógica. Usted puede firewall fuera de estos en la interfaz de límites mediante la comprobación de los parámetros y tener un montón de código como

    void Foo(Something x) {
        if (x==null)
            throw new ArgumentNullException("x");
        ...
    }

    por todo el lugar (mucho de el .Net Framework hace), así que cuando te equivocas, usted consigue un poco más informativo de diagnóstico (la traza de la pila es aún más valioso, sin embargo, y una NRE establece que demasiado). Pero todavía acaba de terminar con una excepción.

    (Aparte: Excepciones como estas – NullReferenceException, ArgumentNullException, ArgumentException, … – normalmente no debe ser atrapados por el programa, sino que sólo significa «desarrollador de este código, no es un error, por favor arreglarlo». Me refiero a estos como un «tiempo de diseño» excepciones; el contraste de estas con el verdadero ‘tiempo de ejecución’ excepciones que ocurren como resultado del entorno en tiempo de ejecución (por ejemplo, FileNotFound) y están destinados a ser potencialmente detecta y controla el programa.)

    Pero al final del día, sólo tienes que escribir el código a la derecha.

    Lo ideal es que la mayoría de NREs nunca iba a pasar porque es ‘null’ es una falta de sentido de valor para muchos tipos de variables, y lo ideal es que el tipo estático sistema de no permitir ‘null’ como un valor para aquellos particular/tipos de variables. A continuación, el compilador le impida la introducción de este tipo de error accidental (descartar ciertas clases de errores son lo que los compiladores y tipo de sistemas son las mejores). Aquí es donde algunos idiomas y los sistemas de tipo excel.

    Pero sin estas características, que acaba de probar el código para asegurarse de que usted no tiene rutas de código con este tipo de error (o posiblemente el uso de algunas herramientas externas que se puede hacer un análisis adicional para usted).

    • +1 para el «tiempo de diseño» excepciones — interesante distinción. He tenido discusiones con la gente en el trabajo acerca de las excepciones en donde he dicho lo mismo. La persona dice: «las excepciones son demasiado lentos», entonces yo digo «pero si tenemos el código es correcto, entonces no vamos a provocar o manejar cualquiera de estas excepciones de todos modos!»
  4. 5

    Usted puede fácilmente verificar una referencia null antes de que se produzca una excepción, pero por lo general esto no es el verdadero problema, por lo que se acaba de lanzar una excepción de todas formas, el código no puede continuar sin ningún tipo de datos.

    A menudo el principal problema no es el hecho de que usted tiene una referencia nula, pero que tiene una referencia nula en el primer lugar. Si una referencia no debe ser null, usted no debe llegar más allá del punto donde la referencia es inicializado sin tener una referencia adecuada.

    • +1 Simple y fácil
  5. 5

    Utilizando Objeto Nulo Patrones es la clave aquí.

    Asegúrese de que usted requiera colecciones de vacío en el caso cuando no están pobladas, en lugar de null. El uso de un valor nulo de la colección cuando una colección vacía haría es confuso y a menudo innecesario.

    Finalmente, hago mis objetos valer para valores no nulos en la construcción siempre que sea posible. De esa manera, yo estoy en la duda, más tarde, como si los valores son nulos, y sólo tiene que realizar nulos cheques donde esencial. Para la mayoría de mis campos y parámetros que puedo asumir que los valores no nulos de las anteriores afirmaciones.

  6. 4

    Realmente si en su idioma hay valores nulos, es posible que suceda. La referencia de objeto null errores provienen de errores en la lógica de la aplicación – por lo menos usted puede evitar todos aquellos que estén obligados a golpear a algunos.

  7. 4

    Uno de los más comunes de referencia null errores que he visto es el caso de las cadenas. Se realizará un control:

    if(stringValue == "") {}

    Pero, la cadena es realmente nula. Debe ser:

    if(string.IsNullOrEmpty(stringValue){}

    También, usted podría ser demasiado cauteloso y verificación de un objeto no es nula antes de intentar acceder a los miembros de los métodos de ese objeto.

    • IsNullOrEmpty a menudo se oculta el problema de que la variable nunca ha sido asignado.
    • Eso suponiendo nulo sólo se utiliza para la inicialización, que no siempre es el caso.
  8. 2

    Uso adecuado de control estructurado de excepciones puede ayudar a evitar tales errores.

    También, de la unidad de pruebas puede ayudar a asegurarse de que su código se comporta como se espera, lo que incluye asegurar que los valores que no son nulos cuando no se supone que debe ser.

  9. 2

    Una de las formas más simples de evitar NullReferenceExceptions es agresivamente verificación de referencias nulas en su constructores de clase/métodos/propiedades de las incubadoras y atraer la atención al problema.

    E. g.

    public MyClass
    {
       private ISomeDependency m_dependencyThatWillBeUsedMuchLater 
    
       //passing a null ref here will cause 
       //an exception with a meaningful stack trace    
       public MyClass(ISomeDependency dependency)
       {
          if(dependency == null) throw new ArgumentNullException("dependency");
    
          m_dependencyThatWillBeUsedMuchLater = dependency;
       }
    
       //Used later by some other code, resulting in a NullRef
       public ISomeDependency Dep { get; private set; }
    }

    En el código anterior, si se pasa una referencia nula, usted sabrá de inmediato que el código de llamada está utilizando el tipo de forma incorrecta. Si no hay null verificación de referencia, el error puede ser oscurecida en muchas maneras diferentes.

    Te darás cuenta de que el .NET framework bibliotecas casi siempre falla temprana y, a menudo, si usted proporciona una referencia null, donde no es válido para hacerlo. Dado que la excepción que explícitamente dice «usted desordenado!» y le dice que por qué, que hace que la detección y corrección de defectuosos código es una tarea trivial.

    He escuchado quejas de algunos desarrolladores que dicen que esta práctica es demasiado detallado y redundantes como una excepción NullReferenceException es todo lo que necesita, pero en la práctica me parece que hace una gran diferencia. Este es especialmente el caso si la pila de llamadas es profunda y/o el parámetro se almacena y su uso es diferido hasta después (tal vez en un subproceso diferente o se oculta en alguna otra forma).

    ¿Qué preferiría tener un ArgumentNullException en el método de entrada, o un oscuro error en las entrañas de ella? Cuanto más se alejan de la fuente de un error, es más difícil de localizar.

  10. 2

    Buenas herramientas de análisis de código puede ayudar aquí. Buena unidad de pruebas también pueden ayudar si usted está utilizando las herramientas que considerar nula como un posible camino a través de su código. Trate de tirar de que el interruptor en la construcción de la configuración que dice «trata a las advertencias de los errores» y ver si usted puede mantener el número de advertencias en su proyecto = 0. Usted puede encontrar las advertencias están diciendo mucho.

    Una cosa a tener en cuenta es que puede ser un buena cosa que usted está lanzando una excepción null – reference. Por qué? porque puede significar que el código que debe han ejecutado no. La inicialización de los valores por defecto es una buena idea, pero debe tener cuidado de que no se terminan escondiendo un problema.

    List<Client> GetAllClients()
    {
        List<Client> returnList = new List<Client>;
        /* insert code to go to data base and get some data reader named rdr */
       for (rdr.Read()
       {
          /* code to build Client objects and add to list */
       }
    
       return returnList;
    }

    Bien, así que esto puede parecer bien, pero dependiendo de las reglas de su empresa, esto puede ser un problema. Seguro, usted nunca tendrá que lanzar una referencia nula, pero tal vez su tabla de Usuario nunca debe estar vacío? ¿Quieres que tu app para estar girando en su lugar, la generación de llamadas de soporte de usuarios que dicen «es solo una pantalla en blanco», o desea elevar una excepción que podrían ser registrados en algún lugar y generar una alerta rápidamente? No olvide validar lo que estás haciendo, así como también el manejo de excepciones. Esta es una de las razones por las que algunos se resisten a tomar valores nulos fuera de nuestras lenguas… lo que hace más fácil encontrar los errores, incluso a pesar de que puede causar algunos nuevos.

    Recuerde: el manejo de excepciones, no ocultarlos.

  11. 1

    Llanura Solución De Código

    Siempre se puede crear una estructura que ayuda a atrapar a null referencia antes los errores mediante el marcado de las variables, propiedades y parámetros como «no se aceptan valores null». He aquí un ejemplo conceptual modelado después de que el camino Nullable<T> obras:

    [System.Diagnostics.DebuggerNonUserCode]
    public struct NotNull<T> where T : class
    {
        private T _value;
    
        public T Value
        {
            get
            {
                if (_value == null)
                {
                    throw new Exception("null value not allowed");
                }
    
                return _value;
            }
            set
            {
                if (value == null)
                {
                    throw new Exception("null value not allowed.");
                }
    
                _value = value;
            }
        }
    
        public static implicit operator T(NotNull<T> notNullValue)
        {
            return notNullValue.Value;
        }
    
        public static implicit operator NotNull<T>(T value)
        {
            return new NotNull<T> { Value = value };
        }
    }

    Utilizaría muy similar a la de la misma manera que utilizaría Nullable<T>, excepto con el objetivo de lograr exactamente lo contrario – para no permitir null. Aquí están algunos ejemplos:

    NotNull<Person> person = null; //throws exception
    NotNull<Person> person = new Person(); //OK
    NotNull<Person> person = GetPerson(); //throws exception if GetPerson() returns null

    NotNull<T> es, implícitamente, escayola y de T así que usted puede utilizarlo en cualquier lugar que necesite. Por ejemplo, usted puede pasar una Person objeto a un método que toma un NotNull<Person>:

    Person person = new Person { Name = "John" };
    WriteName(person);
    
    public static void WriteName(NotNull<Person> person)
    {
        Console.WriteLine(person.Value.Name);
    }

    Como se puede ver arriba como con valores null para poder acceder al valor subyacente a través de la Value de la propiedad. Como alternativa, puede utilizar explícita o implícita, de fundición, se puede ver un ejemplo con el valor de retorno a continuación:

    Person person = GetPerson();
    
    public static NotNull<Person> GetPerson()
    {
        return new Person { Name = "John" };
    }

    O incluso se puede utilizar cuando el método sólo devuelve T (en este caso Person) haciendo un cast. Por ejemplo, el siguiente código justo igual que el código anterior:

    Person person = (NotNull<Person>)GetPerson();
    
    public static Person GetPerson()
    {
        return new Person { Name = "John" };
    }

    Combinar con Extensión

    Combinar NotNull<T> con un método de extensión y puede cubrir más de las situaciones. Aquí es un ejemplo de lo que el método de extensión puede verse como:

    [System.Diagnostics.DebuggerNonUserCode]
    public static class NotNullExtension
    {
        public static T NotNull<T>(this T @this) where T : class
        {
            if (@this == null)
            {
                throw new Exception("null value not allowed");
            }
    
            return @this;
        }
    }

    Y aquí está un ejemplo de cómo podría ser utilizada:

    var person = GetPerson().NotNull();

    GitHub

    Para su referencia hice el código está disponible en GitHub, lo puedes encontrar en:

    https://github.com/luisperezphd/NotNull

  12. 0

    Puede utilizar Objeto nulo patrón y Patrón Caso especial en los casos en que no puede ser un objeto legítimo que puede sustituir null.

    En los casos en que tal objeto no puede ser construido, porque simplemente no hay manera de implementar sus obligatorio operaciones, usted puede confiar en el vacío de colecciones, como en Reducir El Mapa Consultas.

    Otra solución es el Opción de tipo funcional, que es la colección de cero o más elementos. De esta manera, usted tendrá la oportunidad de saltar a la operación que no se puede realizar.

    Estas son las opciones que pueden ayudarle a escribir código sin tener referencias nulas y de ningún valor null cheques.

  13. 0

    Herramientas que pueden ayudar a

    También hay varias bibliotecas que pueden ayudar. El Código de Microsoft, los Contratos se mencionó anteriormente.

    Algunas otras herramientas incluyen Resharper que le puede proporcionar con advertencias, mientras que usted está escribiendo código, especialmente si usted utiliza su atributo: NotNullAttribute

    También hay PostSharp que le permitirá solamente el uso de atributos como este:

    public void DoSometing([NotNull] obj)

    Por hacer eso y hacer PostSharp parte de su proceso de construcción obj se comprueba null en tiempo de ejecución. Ver: PostSharp de verificación null

    La Fody código de tejido de proyecto tiene un plug-in para la aplicación null guardias.

  14. -1

    NullReferenceException puede ser mostrado cuando un método es que no se encuentra en la asamblea,para
    ex m0=mi.GetType().GetMethod(«TellChildToBeQuiet»), donde la asamblea es SportsMiniCar,mi es el ejemplo de MiniVan y TellChildToBeQuiet es un método en la asamblea.
    Podemos evitar esta por ver que esta asamblea la Versión 2.0.0.0 que contiene el método anterior, se coloca en el GAC.
    ejemplo:la Invocación de métodos con parámetros:`

    enter code here
    
    using System;
    using System.Rwflection;
    using System.IO;
    using Carlibraries;
    namespace LateBinding
    {
    public class program
    {
       static void Main(syring[] args)
       {
             Assembly a=null;
             try
             {
                  a=Assembly.Load("Carlibraries");
             }
             catch(FileNotFoundException e)
             {
                   Console.Writeline(e.Message);
                   Console.ReadLine();
                   return;
             }
             Type miniVan=a.GetType("Carlibraries.MiniVan");
             MiniVan mi=new MiniVan();
             mi.TellChildToBeQuiet("sonu",4);
             Console.ReadLine();
           }
       }
       }

    Recuerde actualizar MiniSportsCar Asamblea con TellChildToBeQuiet(cadena ChildName,int count)

Dejar respuesta

Please enter your comment!
Please enter your name here