Avatar billede morf4r Nybegynder
24. november 2006 - 14:37 Der er 14 kommentarer og
1 løsning

Object reference not set to an instance of an object.

Hej, jeg  har en form1 hvor jeg skriver et kundeid ind i en textbox.
det kundeid skal så bare komme frem når form2 loader i en label.

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            kunde k = new kunde(Convert.ToInt32(textBox1.Text));

            Form2 form2 = new Form2();
            form2.Show();
        }
    }
}
public class kunde
{
    private int _kundeid;

    public kunde(int kundeid)
    {
        _kundeid = kundeid;
    }

    public int getKundeid
    {
        get { return _kundeid; }
        set { _kundeid = value; }
    }
}
public class test
{
    private kunde kunde; 

    public kunde getKunde()
    {
        return kunde;
    }
}

namespace Test
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            test test = new test();
            label1.Text = test.getKunde().getKundeid.ToString();
         
        }
    }
}


label1.Text = test.getKunde().getKundeid.ToString();
giver dog fejlen:
Object reference not set to an instance of an object.

Hvad gør jeg forkert?
Avatar billede bulgroz Nybegynder
24. november 2006 - 15:13 #1
Din Tesk klasse laver jo ingenting

public class test
{
    private kunde kunde; 

    public kunde getKunde()
    {
        return kunde;
    }
}

Enten laver du en default constructor på kunde som sørger for at _kundeid altid bliver assignet, eller også kalder du specifikt den rette constructor i din test klasse.
Avatar billede bulgroz Nybegynder
24. november 2006 - 15:29 #2
Med lidt mindre ændringer kalder du constructoren, som sørger for at lave en instans af Kunde i din test klasse.

        public Form1()
        {
            InitializeComponent();

            Test test = new Test();
            MessageBox.Show(test.Kunde.Id.ToString());
        }

        public class Kunde
        {
            private int kundeId;

            public Kunde(int id)
            {
                this.kundeId = id;
            }

            public int Id
            {
                get { return this.kundeId; }
                set { this.kundeId = value; }
            }
        }

        public class Test
        {
            private Kunde kunde = new Kunde(1234);

            public Kunde Kunde
            {
                get
                {
                    return kunde;
                }
            }
        }

Nb! det er en god ide at følge navngivningsstandarder. f.ek. bør dine klassenavne være med stort forbogstav, og dine medlems variable med lille. Ellers er det svært at se forskel i din kode.
Avatar billede bulgroz Nybegynder
24. november 2006 - 15:37 #3
Det kan godt være at min forklaring blev lidt forvirrende, men altså...
Den egentlige fejlårsag er at du mangler at kalde constructoren på din Kunde klasse (i din test klasse).
Avatar billede morf4r Nybegynder
24. november 2006 - 15:59 #4
istedet for 1234, hvordan får jeg så værdien fra min textbox på form1 hvis jeg bruger dit eksempel?
Avatar billede bulgroz Nybegynder
24. november 2006 - 17:36 #5
Det mangler du at tage højde for selv. Du bør lave en constructor på din test klasse, som kan tage kunde Id.

Se følgende eksempel:

        public class Kunde
        {
            private int kundeId;

            /// <summary>
            /// Opretter en instans af kunde uden angivelse af Id.
            /// </summary>
            public Kunde()
            {
                this.kundeId = -1;
            }

            /// <summary>
            /// Opretter en instans af kunde med angivelse af kunde Id.
            /// </summary>
            /// <param name="id">Kundens Id nummer.</param>
            public Kunde(int id)
            {
                this.kundeId = id;
            }

            /// <summary>
            /// Returnerer eller sætter kundens Id.
            /// </summary>
            public int Id
            {
                get { return this.kundeId; }
                set { this.kundeId = value; }
            }
        }

        public class Test
        {
            private Kunde kunde;

            public Test()
            {
                this.kunde = new Kunde();
            }

            public Test(int id)
            {
                this.kunde = new Kunde(id);
            }

            public Kunde Kunde
            {
                get
                {
                    return this.kunde;
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Test test2 = new Test(int.Parse(this.textBox1.Text));
            MessageBox.Show(test2.Kunde.Id.ToString());
        }

Egentligt kan du undlade din testklasse, da det eneste den gør er at lave en ny kunde. Men du har nok en bagtanke med denne klasse så jeg har beholdt den i eksemplet.

Mit eksempel er udvidet en smule. Kunde har nu to constructorer. Den ene uden argumenter opretter en kunde med kundeId -1 (hvis man har behov for dette, ellers kan den blot slettes). Den anden tager et Kunde Id. Samme constructorer er replikeret til test klassen.
Avatar billede morf4r Nybegynder
24. november 2006 - 17:55 #6
Hvordan overfører jeg så værdien jeg skriver i textboxen til label1.text på form2?
Jeg kan ikke lave en new test da værdien så bare bliver -1.
Avatar billede bulgroz Nybegynder
24. november 2006 - 18:38 #7
Du bør lave en constructor på din form2 som tager din kunde.
Noget i stil med:

        public Form2(Kunde kunde) : this()
        {
            this.kunde = kunde;
        }

this() kalder den defaulte constructor som indeholder kaldet til InitializeComponent(). Med andre ord, hvis din nye constructor ikke kalder this() må du duplikere denne linie kode.


I din form2 har du en label som skal vise kundens Id..

this.label1.Text = this.kunde.Id.ToString();

Du kan indsætte denne linie i din constructor, i FormLoad eller når du trykker på enknap.
Avatar billede bulgroz Nybegynder
24. november 2006 - 18:39 #8
Vedr. -1, så var det blot et eksempel på flere constructorer. Hvis dette ikke passer ind i din løsning kan du blot udelade constructoreren som ikke tager parametre.
Avatar billede bulgroz Nybegynder
24. november 2006 - 18:56 #9
Eksemplet kan derfor se således ud:

    public class Kunde
    {
        private int kundeId;

        /// <summary>
        /// Opretter en instans af kunde med angivelse af kunde Id.
        /// </summary>
        /// <param name="id">Kundens Id nummer.</param>
        public Kunde(int id)
        {
            this.kundeId = id;
        }

        /// <summary>
        /// Returnerer eller sætter kundens Id.
        /// </summary>
        public int Id
        {
            get { return this.kundeId; }
            set { this.kundeId = value; }
        }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Kunde kunde = new Kunde(int.Parse(this.textBox1.Text));

                Form2 form2 = new Form2(kunde);
                form2.ShowDialog();
            }
            catch(FormatException)
            {
                MessageBox.Show("Fejl i Kunde ID");
            }
        }
    }

    public partial class Form2 : Form
    {
        private Kunde kunde;

        private Form2()
        {
            InitializeComponent();
        }

        public Form2(Kunde kunde) : this()
        {
            if (kunde == null)
            {
                throw new ArgumentNullException("kunde");
            }

            this.kunde = kunde;
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            if (this.kunde != null)
            {
                this.label1.Text = this.kunde.Id.ToString();
            }
            else
            {
                this.label1.Text = "Ingen Kunde!";
            }
        }
    }
Avatar billede bulgroz Nybegynder
24. november 2006 - 18:57 #10
Nb. Eksemplet medtager ikke din test klasse!
Avatar billede morf4r Nybegynder
24. november 2006 - 20:01 #11
Tak, det virker.
Synes dog jeg har lavet det før hvor det var en anelse nemmere (kunne ikke huske hvordan, derfor denne tråd).
Kunne især ikke huske:

Form2 form2 = new Form2(kunde);
og
public Form2(Kunde kunde) : this()

Kan man egentligt ikke skrive linje 2 anderledes? synes ikke at jeg har set det sådan før (med : this())
Avatar billede bulgroz Nybegynder
24. november 2006 - 20:56 #12
Ja som jeg skrev tidligere...
"this() kalder den defaulte constructor som indeholder kaldet til InitializeComponent(). Med andre ord, hvis din nye constructor ikke kalder this() må du duplikere denne linie kode."

Med andre ord:

        public Form2(Kunde kunde)
        {
            if (kunde == null)
            {
                throw new ArgumentNullException("kunde");
            }

            this.kunde = kunde;

            InitializeComponent();
        }

Giver samme resultat, men har du også en constructor uden parametre vil du som minimum have InitializeComponent() som redundant kode, hvilket man jo forsøger at undgå hvis man kan.

Når man skriver:
public Form2(Kunde kunde) : this()
     
resulterer det i at man først kalder constructoren uden parametre. Når denne er færdig med hvad den så en måtte lave (i mit eksempel InitializeComponent()) udføres den aktuelle constructor "Form2(Kunde kunde" som assigner kunde parametren til den private kunde variabel.
Avatar billede bulgroz Nybegynder
24. november 2006 - 21:05 #13
Med hensyn til "simplere"...

Man kan jo skrive kode på mage måder. Mit eksempel anvender constructoren til at overføre Kunde, men du kan også anvende en property til det samme. Det afhænger af hvad du ønsker i din løsning.
Derudover har jeg taget mig den frihed at checke lidt for om dine objekter bliver korrekt oprettet.

try
{
  ...
}
catch(FormatException)
{
  MessageBox.Show("Fejl i Kunde ID");
}

sikrer dig at din tekst som er tastet ind i din tekst streng kan konverteres korrekt.
hvis du f.eks. skriver "Åhh Abe" på i din TextBox og trykker på din knap kaster int.Parse en FormatException som fanges med catch(FormatException) og der vises herefteren venlig fejlmeddelelse.
Avatar billede morf4r Nybegynder
25. november 2006 - 00:17 #14
Smid et svar, tak for hjælpen.
Avatar billede bulgroz Nybegynder
25. november 2006 - 06:16 #15
svar...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester