Referencia de objeto no establecida como instancia de un objeto

Iniciado por Fixxed, 11 Marzo 2016, 15:03 PM

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

Fixxed

Hola, tengo el siguiente problema. He creado un array de clases, pero cuando quiero inicializarlo (Es decir, poner todos sus valores a 0), me tira el famoso error:

CitarAn unhandled exception of type 'System.NullReferenceException'

Referencia a objeto no establecida como instancia de un objeto.

Alguien sabe a que se debe?? Les dejo el código:

Form1.cs
Código (csharp) [Seleccionar]
public void CargarArray(ref Pedido[] peds)
        {
            int i = 0;
            for (i = 0; i < 500; i++)
            {
                peds[i].cliente = "NADA";
                peds[i].producto = "NADA";
                peds[i].cantidad = 0;
                peds[i].preciou = 0;
                peds[i].calle = "NADA";
                peds[i].num = 0;
                peds[i].distrito = "NADA";
            }
}

private void ImprimirClientes(object obj, PrintPageEventArgs ev)
        {
            Pedido[] peds = new Pedido[500];

            CargarArray(ref peds);
}


Pedido.cs
Código (csharp) [Seleccionar]
public class Pedido
    {
        public String cliente;
        public String producto;
        public int cantidad;
        public double preciou;
        public String calle;
        public int num;
        public String distrito;
    }

Eleкtro

#1
Cita de: Fixxed en 11 Marzo 2016, 15:03 PMAlguien sabe a que se debe??

El famoso mensaje de error se explica por si solo, estás intentando referenciar un objeto que NO ha sido inizializado.

Para que lo entiendas mejor: En el código que has mostrado, estás inicializando el Array, pero no los valores del Array, los valores son todo nulos.

Dicho esto, para no perder la "elegancia" del código puedes utilizar una query Linq-To-Objects de la siguiente manera:

Vb.Net
Código (vbnet) [Seleccionar]
Dim peds As Pedido() = (New Pedido(499) {}).Select(Function(element) New Pedido).ToArray()

C#:
Código (csharp) [Seleccionar]
var peds = new Pedido[499].Select(element => new Pedido()).ToArray();

O puedes crear una extensión de método rehutilizable para cualquier ocasión:

Vb.Net:
Código (vbnet) [Seleccionar]
' By Elektro

Public Module ArrayExtensions

   <Runtime.CompilerServices.Extension>
   Public Sub InitializeElements(Of T As New)(ByVal sender As T())

       For index As Integer = 0 To (sender.Length - 1)

           If (sender(index) IsNot Nothing) Then

               If sender(index).GetType.GetInterfaces.Contains(GetType(IDisposable)) Then
                   DirectCast(sender(index), IDisposable).Dispose()
                   sender(index) = Nothing
               End If

           End If

           sender(index) = New T

       Next index

   End Sub

End Module


Modo de empleo:
Código (vbnet) [Seleccionar]
Dim peds As Pedido() = (New Pedido(499) {})
peds.InitializeElements()


Traducción online a C#:
Código (csharp) [Seleccionar]
// By Elektro

public static class ArrayExtensions {

[Runtime.CompilerServices.Extension()]
public static void InitializeElements<T>(T[] sender) where T : new() {

for (int index = 0; index <= (sender.Length - 1); index++) {

if ((sender(index) != null)) {
if (sender(index).GetType.GetInterfaces.Contains(typeof(IDisposable))) {
((IDisposable)sender(index)).Dispose();
sender(index) = null;
}
}
sender(index) = new T();
}
}
}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//=======================================================


Modo de empleo:
Código (csharp) [Seleccionar]
var peds = new Pedido[499]
peds.InitializeElements()





Por último, ten presente que puedes (y deberías) inicializar el valor por defecto de los campos de tu Type, desde el constructor de tu Type, y no desde un método local cualqueira.

Código (csharp) [Seleccionar]
public sealed class Pedido
{

public string Cliente { get; set; }
public string Producto { get; set; }
public int Cantidad { get; set; }
public double Precio { get; set; }
public string Calle { get; set; }
public int Num { get; set; }
public string Distrito { get; set; }

public Pedido()
{
this.Cliente = "NADA";
this.Producto = "NADA";
this.Calle = "NADA";
this.Distrito = "NADA";
}

}

(no es necesario hacerlo para los tipos numéricos)

Saludos!