No encuentro el error NullReferenceException

Iniciado por Debyon, 2 Noviembre 2017, 19:32 PM

0 Miembros y 1 Visitante están viendo este tema.

Debyon

Estoy usando el Visual Studio 7.2.2 para Mac. Aprendi C# hace un par de años y ahora estoy volviendo a recordar todo porque he estado como 1 año sin hacer nada. El caso es que haciendo un programa simple de consola que leyera un array de 2 dimensiones con unos datos predefinidos y luego los mostrara en pantalla. Supuestamente te pide el modelo a Buscar (que estan apuntados todos en el source), luego si hay 1 sola coincidencia imprime los datos de ese modelo en particular, si hay mas de 1 coincidencia imprime toda la lista de coincidencias y si no hay ninguna coincidencia muestra un mensaje diciendo que no ha encontrado nada.

El caso es que me sale System.NullReferenceException justo despues de poner la palabra para buscar y quiza soy yo que he perdido practica pero no encuentro el fallo. Os dejo el source para que lo veais. Aclaro que me gustaria que me explicarais el fallo en lugar de corregir sin mas el source porfavor. Graciaaas!!


Código (csharp) [Seleccionar]
using System;

namespace ListadeModelos
{
   class Program
   {

       static string[,] modelos = new string[6,9];//contiene los datos de los modelos

       static void Main(string[] args)
       {
           string busqueda;//palabra que se usara para buscar entre los modelos del array

           while(true)
           {
               Console.Write("Modelo a buscar:       ");
               busqueda = Console.ReadLine();

               if (busqueda.ToUpper() == "SALIR")//para salir del programa
               {
                   break;
               }

               Buscar(busqueda);
           }
       }

       static void Buscar(string busqueda)//Busca en el array un resultado y luego ejecuta el metodo para cada caso
       {
           int contador = 0; // cuenta la cantidad de veces que encuentra un resultado
           int encontrado = 0; //contendra el numero de array para en caso de encontrar solo un resultado saber cual es.
           for (int x = 0; x < modelos.GetLength(0) ; x++)
           {
               if (modelos[x, 0].ToUpper().Contains(busqueda.ToUpper()))
               {
                   contador++;
                   encontrado = x;
               }
           }

           if (contador == 1)
           {
               Console.WriteLine("\n\n");
               Imprimir(encontrado);
           }
           else if (contador > 1)
           {
               Console.WriteLine("\n\n");
               Imprimirlista(busqueda);
           }
           else
           {
               Console.WriteLine("\n\n");
               Console.WriteLine("No se han encontrado resultados.");
           }
       }

       static void Imprimir(int encontrado)//Imprime en pantalla los datos en caso de que solo haya una coincidencia en la busqueda
       {
           for (int x = 0; x < modelos.GetLength(1); x++)
           {
               if(modelos[encontrado, x].Contains("Nulo"))
               {
                   break;
               }
               Console.WriteLine(modelos[encontrado, x]);
           }
       }

       static void Imprimirlista(string busqueda)//Imprime en pantalla la lista de nombres de los modelos encontrados en caso de que haya mas de 1 coincidencia
       {
           for (int x = 0; x < modelos.GetLength(0); x++)
           {
               if (modelos[x,0].ToUpper().Contains(busqueda.ToUpper()))
               {
                   Console.WriteLine(modelos[x,0]);
               }
           }
       }

       static void CrearLista()//Crea la lista a partir del array asignando todos los campos como "Nulo" y despues rellenandolos manualmente.
       {
           //creacion de la list

           for (int x = 0; x < modelos.GetLength(0); x++)
           {
               for (int y = 0; y < modelos.GetLength(1); y++)
               {
                   modelos[x, y] = "Nulo";
               }
           }

           modelos[0, 0] = "Aitana Blanco";
           modelos[0, 1] = "Base D.Doble";
           modelos[0, 2] = "FC-9922/417D";
           modelos[0, 3] = "Peso:   55g";
           modelos[0, 4] = "Dens:   155";
           modelos[0, 5] = "Nulo";

           modelos[1, 0] = "Aitana Gris";
           modelos[1, 1] = "Base D.Doble";
           modelos[1, 2] = "Base Aitana Jet";
           modelos[1, 3] = "Peso:   55g";
           modelos[1, 4] = "Dens:   155";
           modelos[1, 5] = "Nulo";

           modelos[2, 0] = "Alaska Gris";
           modelos[2, 1] = "Engobe Campana";
           modelos[2, 2] = "Engobe Gres Campana";
           modelos[2, 3] = "Peso:   50g";
           modelos[2, 4] = "Dens:   180";
           modelos[2, 5] = "Base Campana";
           modelos[2, 6] = "MGM-0222";
           modelos[2, 7] = "Peso:   55g";
           modelos[2, 8] = "Dens:   180";

           modelos[3, 0] = "Andes Marengo";
           modelos[3, 1] = "Base D.Doble";
           modelos[3, 2] = "Base Etna Jet";
           modelos[3, 3] = "Peso:   50g";
           modelos[3, 4] = "Dens:   155";
           modelos[3, 5] = "Nulo";

           modelos[4, 0] = "Andes Sage";
           modelos[4, 1] = "Base D.Doble";
           modelos[4, 2] = "M81/202";
           modelos[4, 3] = "Peso:   50g";
           modelos[4, 4] = "Dens:   155";
           modelos[4, 5] = "Nulo";

           modelos[5, 0] = "Arcalis Mix";
           modelos[5, 1] = "Base D.Doble";
           modelos[5, 2] = "EG-445/18992";
           modelos[5, 3] = "Peso:   55g";
           modelos[5, 4] = "Dens:   152";
           modelos[5, 5] = "Nulo";
       }
   }
}

Eleкtro

#1
Hola.

Por favor, lee las normas del subforo y utiliza las etiquetas GeShi para darle formato a los bloques de código.. . .

Respondiendo a tu pregunta, el tipo de exceptión de referencia nula, la cual habla por si sola, te está dando una pista de que hay un miembro sin inicializar. Para ser más específicos: nunca inicializas los elementos del Array antes de ponerte a buscar coincidencias en los elementos de dicho Array, o dicho de otra forma: nunca llamas al método "CrearLista" antes del método "Buscar", se puede decir que es un típico "fallo tonto" sin mayor importancia.




Con respecto al código que tienes actualmente, en general, creo que te estás complicando demasiado la vida utilizando un Array multidimensionál sin un motivo que sea razonable aparentemente... aunque solamente fuese con la intención de "recordar y practicar lo aprendido", hay cosas más productivas que poder practicar, ya que los Arrays multidimensioanles y/o los Arrays irregulares (Jagged Arrays) poco o nada los vas a necesitar usar a la larga para un escenario de la vida real, así que te sugiero que definas un tipo personalizado (clase o estructura) para representar la información de un "Modelo", y a partir de ahí tan solo tienes que construir una colección genérica de varios elementos (varios "Modelo") con la que trabajar de forma mucho más sencilla, robusta y sofisticada, en fin, una opción óptima, pues ten en cuenta que además los tipos de colecciones genéricas como por ejemplo Lis<T> ya exponen miembros para buscar y devolver coincidencias en los elementos de la colección, así como buscar el índice de un elemento y etcétera, son cosas que haces en tu código... lo que significa que te ahorrarías la necesidad de implementar esas...metodologías de búsqueda por ti mismo con un Array multidimensional.

Ejemplo de implementación:

Código (csharp) [Seleccionar]
using System;
using System.Collections.Generic;
using System.Threading;


Código (csharp) [Seleccionar]
/// <summary>
/// Represents a model.
/// </summary>
public sealed class Model : IComparable<Model> {

   /// <summary>
   /// Gets the model's name.
   /// </summary>
   public string Name { get; }
   /// <summary>
   /// Gets the model's weight, in grams.
   /// </summary>
   public int Weight { get; }
   // etc...

   /// <summary>
   /// Prevents a default instance of the <see cref="Model"/> class from being created.
   /// </summary>
   private Model() { }

   /// <summary>
   /// Initializes a new instance of the <see cref="Model"/> class.
   /// </summary>
   /// <param name="name">
   /// The model's name.
   /// </param>
   /// <param name="weight">
   /// The model's weight.
   /// </param>
   /// <exception cref="ArgumentNullException">
   /// name - Name can't be null.
   /// </exception>
   /// <exception cref="ArgumentOutOfRangeException">
   /// weight - A value greater than 0 is required.
   /// </exception>
   public Model(string name, int weight) {
       if (string.IsNullOrWhiteSpace(name)) {
           throw new ArgumentNullException("name", "Name can't be null.");
       }
       if (weight <= 0) {
           throw new ArgumentOutOfRangeException("weight", weight, "A value greater than 0 is required.");
       }

       this.Name = name;
       this.Weight = weight;
   }

   /// <summary>
   /// Compares the current <see cref="Model"/> with another <see cref="Model"/>
   /// and returns an integer value that indicates whether the current instance precedes, follows,
   /// or occurs in the same position in the sort order as the other <see cref="Model"/>.
   /// </summary>
   /// <param name="other">
   /// Other <see cref="Model"/> to compare with this <see cref="Model"/>.
   /// </param>
   /// <returns>
   /// An integer value that indicates the relative order of the objects being compared.
   /// </returns>
   public int CompareTo(Model other) {
       return string.Compare(this.Name, other.Name, StringComparison.Ordinal);
   }

   /// <summary>
   /// Returns a <see cref="String"/> that represents this <see cref="Model"/>.
   /// </summary>
   /// <returns>
   /// A <see cref="String"/> that represents this <see cref="Model"/>.
   /// </returns>
   public override string ToString() {
       return string.Format("{{ {0}:{1}, {2}:{3} }}",
                            nameof(this.Name), this.Name,
                            nameof(this.Weight), this.Weight);
   }

}


Código (csharp) [Seleccionar]
class Program {
   
   private static SortedSet<Model> Models; // Note that collection elements are sorted by Model.Name property.

   static void Main(string[] args) {
       string input = null;
       IEnumerable<Model> matches = null;

       Program.BuildModelCollection();
       while (true) {
           Console.Write("Input a model's name to match: ");
           input = Console.ReadLine();
           matches = Program.MatchModelName(input);
           Program.PrintMathes(matches);
       }
   }
   
   private static void BuildModelCollection() {
       Program.Models = new SortedSet<Model> {
           new Model("Aitana Blanco", 55),
           new Model("Aitana Gris", 55),
           new Model("Arcalis Mix", 55),
           new Model("Andes Marengo", 50),
           new Model("Andes Sage", 50),
           new Model("Alaska Gris", 50)
       };
   }

   private static IEnumerable<Model> MatchModelName(string input) {
       foreach (Model m in Program.Models) {
           if (m.Name.ToLower().Contains(input.ToLower())) {
               yield return m;
           }
       }
   }

   private static void PrintMathes(IEnumerable<Model> matches) {
       if (matches == null) {
           Console.WriteLine("No results found.");
           return;
       }

       int count = 0;
       foreach (Model m in matches) {
           Console.WriteLine(string.Format("[{0}]: {1}", Interlocked.Increment(ref count), m.ToString()));
       }
       Console.WriteLine();
   }
   
}


Nota: El código fuente de arriba ha sido desarrollado bajo Windows con el framework multiplataforma .NET Core para soportar tu sistema operativo.

Resultado de ejecución:



PD: Evidentemente la clase "Modelo" es tan solo un ejemplo simplificado el cual lo adaptarías y lo extenderias para cubrir el resto de necesidades que tengas en tu escenario de trabajo.

Un saludo.