Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Bob1098 en 29 Diciembre 2014, 15:32 pm



Título: Problema con Objeto C#
Publicado por: Bob1098 en 29 Diciembre 2014, 15:32 pm
Hola, bueno estaba tratando de hacer un programilla en C# que sirviera para resolver sudokus, y de momento solo llevo hecho el cronometro de tiempo y los botones para controlar si comenzar, pausar o detener el juego. Para generar los números he pensado almacenarlos en una matriz int, y para mostrarlos pensé que sería mas cómodo utilizar una matriz de la clase TextBox en la que guardo todos los controles que tengo donde quiero mostrar los números, y asi con un ciclo for poder pasar de un textbox a otro sin problema.

La cuestión es que al darle valores a la propiedad Text de los TextBox almacenados en la matriz obtengo una excepción.

Código:
Código
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10.  
  11. namespace Sudoku
  12. {
  13.    public partial class Form1 : Form
  14.    {
  15.        byte s, m, h;
  16.        bool paused = false;
  17.        bool gameStarted = false;
  18.        int[,] numeros = new int[9,9];
  19.        TextBox[,] Numeros = new TextBox[9, 9];
  20.  
  21.        public Form1()
  22.        {
  23.            InitializeComponent();
  24.        }
  25.  
  26.        private void UnirTextBox()
  27.        {
  28.            //Celda 1
  29.            Numeros[0, 0] = nTextBox1;
  30.            Numeros[0, 1] = nTextBox2;
  31.            Numeros[0, 2] = nTextBox3;
  32.            Numeros[1, 0] = nTextBox4;
  33.            Numeros[1, 1] = nTextBox5;
  34.            Numeros[1, 2] = nTextBox6;
  35.            Numeros[2, 0] = nTextBox7;
  36.            Numeros[2, 1] = nTextBox8;
  37.            Numeros[2, 3] = nTextBox9;
  38.  
  39.            //Celda 2
  40.            Numeros[0, 3] = nTextBox10;
  41.            Numeros[0, 4] = nTextBox11;
  42.            Numeros[0, 5] = nTextBox12;
  43.            Numeros[1, 3] = nTextBox13;
  44.            Numeros[1, 4] = nTextBox14;
  45.            Numeros[1, 5] = nTextBox15;
  46.            Numeros[2, 3] = nTextBox16;
  47.            Numeros[2, 4] = nTextBox17;
  48.            Numeros[2, 5] = nTextBox18;
  49.  
  50.            //Celda 3
  51.            Numeros[0, 6] = nTextBox19;
  52.            Numeros[0, 7] = nTextBox20;
  53.            Numeros[0, 8] = nTextBox21;
  54.            Numeros[1, 6] = nTextBox22;
  55.            Numeros[1, 7] = nTextBox23;
  56.            Numeros[1, 8] = nTextBox24;
  57.            Numeros[2, 6] = nTextBox25;
  58.            Numeros[2, 7] = nTextBox26;
  59.            Numeros[2, 8] = nTextBox27;
  60.        }
  61.  
  62.        private void GenerarNumeros()
  63.        {
  64.            Random rnd = new Random();
  65.            for (int i = 0; i < 9; i++)
  66.            {
  67.                for (int j = 0; j < 9; j++)
  68.                {
  69.                    numeros[i, j] = rnd.Next(1, 9);
  70.                    Numeros[i, j].Text = numeros[i, j].ToString(); //Aquí es el punto donde obtengo el error de ejecución.
  71.                }
  72.            }
  73.        }
  74.  
  75.        private void Preparacion()
  76.        {
  77.            UnirTextBox();
  78.            GenerarNumeros();
  79.        }
  80.  
  81.        private void startButton_Click(object sender, EventArgs e)
  82.        {
  83.            Preparacion();
  84.            s = 1; m = 0; h = 0;
  85.            timeTextBox.Text = "0:00:00";
  86.            timer1.Start();
  87.            gamePanel.Enabled = true;
  88.            gameStarted = true;
  89.        }
  90.  
  91.        private void pauseButton_Click(object sender, EventArgs e)
  92.        {
  93.            if (gameStarted)
  94.            {
  95.                if (!paused)
  96.                {
  97.                    timer1.Stop();
  98.                    gamePanel.Enabled = false;
  99.                    paused = true;
  100.                }
  101.                else
  102.                {
  103.                    timer1.Start();
  104.                    gamePanel.Enabled = true;
  105.                    paused = false;
  106.                }
  107.            }
  108.        }
  109.  
  110.        private void cancelButton_Click(object sender, EventArgs e)
  111.        {
  112.            timer1.Stop();
  113.            gamePanel.Enabled = false;
  114.            timeTextBox.Text = "0:00:00";
  115.            s = 0; m = 0; h = 0;
  116.            gameStarted = false;
  117.        }
  118.  
  119.        private void checkButton_Click(object sender, EventArgs e)
  120.        {
  121.  
  122.        }
  123.  
  124.        private void timer1_Tick(object sender, EventArgs e)
  125.        {
  126.            if (m < 10)
  127.            {
  128.                if (s < 10) timeTextBox.Text = h + ":" + "0" + m + ":" + "0" + s;
  129.                else timeTextBox.Text = h + ":" + "0" + m + ":" + s;
  130.            }
  131.            else
  132.            {
  133.                if (s < 10) timeTextBox.Text = h + ":" + m + ":" + "0" + s;
  134.                else timeTextBox.Text = h + ":" + m + ":" + s;
  135.            }
  136.            s++;
  137.            if (s == 60)
  138.            {
  139.                s = 0;
  140.                m++;
  141.            }
  142.            if (m == 60)
  143.            {
  144.                m = 0;
  145.                h++;
  146.            }
  147.        }
  148.    }
  149. }
  150.  

La excepción dice así:
Excepción no controlada del tipo 'System.NullReferenceException' en Sudoku.exe

Información adicional: Referencia a objeto no establecida como instancia de un objeto.

Espero que sepan a que se debe. Y ya de paso si conocen algún otro método para guardar los textbox que no sea manualmente como yo he hecho =P.


Título: Re: Problema con Objeto C#
Publicado por: Shell Root en 29 Diciembre 2014, 16:09 pm
Printea las variables i, j en:
Código
  1.        private void GenerarNumeros()
  2.       {
  3.           Random rnd = new Random();
  4.           for (int i = 0; i < 9; i++)
  5.           {
  6.               for (int j = 0; j < 9; j++)
  7.               {
  8.                   MessageBox.Show("i = " + i + " | j = " + j);
  9.                   numeros[i, j] = rnd.Next(1, 9);
  10.                   Numeros[i, j].Text = numeros[i, j].ToString(); //Aquí es el punto donde obtengo el error de ejecución.
  11.               }
  12.           }
  13.       }


Título: Re: Problema con Objeto C#
Publicado por: Eleкtro en 29 Diciembre 2014, 17:50 pm
La excepción se produce por que intentas acceder a un objeto que no ha sido inicializado.

Comprueba si esto no te lanza una null-reference exception:
Código
  1. Numeros(i, j) = new TextBox();
  2. Numeros(i, j).Text = Convert.ToString(numeros(i, j));

Si te funciona, comprueba que nTextBox1 y siguientes están instanciados.

Saludos


Título: Re: Problema con Objeto C#
Publicado por: Bob1098 en 29 Diciembre 2014, 21:49 pm
La excepción se produce por que intentas acceder a un objeto que no ha sido inicializado.

Comprueba si esto no te lanza una null-reference exception:
Código
  1. Numeros(i, j) = new TextBox();
  2. Numeros(i, j).Text = Convert.ToString(numeros(i, j));

Si te funciona, comprueba que nTextBox1 y siguientes están instanciados.

Saludos

Si, ya no salta la excepción, pero no hace nada no se muestran los números. A que te refieres con instanciar los textbox? Tengo que hace nTextBox1 = new TextBox con todos? :S


Título: Re: Problema con Objeto C#
Publicado por: El Benjo en 30 Diciembre 2014, 01:02 am
Sí. Como menciona Elektro debes hacer eso con cada uno de los textbox (si pones atención al código verás que eso está resuelto porque la asignación está dentro del bucle for()). Recuerda que una variable del tipo de cualquier objeto (a diferencia de los tipos primitivos como int, bool, etc) es un puntero que guarda la dirección de memoria donde existen las propiedades del objeto. Cuando tú creas una variable de la forma:

Código
  1. TextBox VarObjeto;

La variable 'VarObjeto' no apunta a ninguna dirección de memoria. Y cuando haces:

Código
  1. VarObjeto = new TextBox();

Lo que haces es crear un nuevo objeto de la clase 'TextBox' y asignar a 'VarObjeto' la dirección de memoria donde reside el objeto.

Y eso de que no te muestre nada es porque al crear una nueva instancia para cada objeto del arreglo dejan de hacer referencia a los textbox que tienes creados en el formulario. Ahora, esto es lo interesante: Si previamente hacían referencia a los textbox que tienes en el formulario, ¿por qué te saltaba la excepción como si fueran objetos nulos? Espero que Elektro o alguien más nos pueda dar explicación a esto. :/


Título: Re: Problema con Objeto C#
Publicado por: Bob1098 en 30 Diciembre 2014, 12:19 pm
Sí. Como menciona Elektro debes hacer eso con cada uno de los textbox (si pones atención al código verás que eso está resuelto porque la asignación está dentro del bucle for()). Recuerda que una variable del tipo de cualquier objeto (a diferencia de los tipos primitivos como int, bool, etc) es un puntero que guarda la dirección de memoria donde existen las propiedades del objeto. Cuando tú creas una variable de la forma:

Código
  1. TextBox VarObjeto;

La variable 'VarObjeto' no apunta a ninguna dirección de memoria. Y cuando haces:

Código
  1. VarObjeto = new TextBox();

Lo que haces es crear un nuevo objeto de la clase 'TextBox' y asignar a 'VarObjeto' la dirección de memoria donde reside el objeto.

Y eso de que no te muestre nada es porque al crear una nueva instancia para cada objeto del arreglo dejan de hacer referencia a los textbox que tienes creados en el formulario. Ahora, esto es lo interesante: Si previamente hacían referencia a los textbox que tienes en el formulario, ¿por qué te saltaba la excepción como si fueran objetos nulos? Espero que Elektro o alguien más nos pueda dar explicación a esto. :/

Efectivamente, es lo que tu dices al final de tu respuesta, no comprendo por qué motivo saltaba la excepción como si se tratasen de objetos nulos, si ya tenían asignada una dirección de memoria... Aún así gracias por las repsuestas a todos. :)