wiki:YleisiaVirheita
Last modified 7 years ago Last modified on 2011-05-31 16:08:34

Apuja ohjelmointiin » Yleisiä virheitä

Ohjelmaa kirjoittaessasi saattaa Visual Studio ilmoittaa monenlaisista virheistä "punakynällä". Usein tämä johtuu vain siitä, että virheitä näytetään vaikket olisi kerennyt kirjoittaa lausetta loppuun asti. Jos olet kuitenkin kirjoittanut mielestäsi kaiken oikein, mutta virheitä esiintyy edelleen, katso löytyykö virhettä tämän sivun ohjeista.

Kun käännät ohjelmaa (Visual Studiossa F6-näppäin) tai yrität ajaa sitä (F5-näppäin), kaikki ohjelmaan jääneet kääntäjän virheet tulevat näkyviin listana ruudun alareunaan. Tuplaklikkaamalla virhetta hyppäät koodissa siihen kohtaan missä virhe esiintyy. Virheitä saattaa näkyä kerralla paljon, mutta ei kannata hätääntyä, sillä usein suuri osa virheistä on seurausta muista virheistä. Tämän vuoksi virheiden korjaaminen kannattaa aloittaa ensimmäisestä virheestä.

Muista kuitenkin, että vaikka kaikki käännöksen virheet olisikin korjattu, se ei suinkaan takaa sitä että ohjelma toimisi oikein!

Tässä yleisimpiä virheitä.

Tyyppiä tai nimiavaruutta ei löydy

Viesti:

The type or namespace name 'PhysisObject' could not be found (are you missing a using directive or an assembly reference?)

Syitä:

  • Oletko kirjoittanut esim. jonkun aliohjelman tai tyypin nimen väärin? Katso sanoja, jotka on väritetty punakynällä. Äskeisessä virheviestissä PhysisObject pitäisi kirjoittaa PhysicsObject. Käytä Visual Studion koodin täydennystä kirjoitusvirheiden välttämiseksi.
  • Jokin kirjasto puuttuu (kts Kirjastojen liittäminen projektiin: wiki, video)
  • Jokin using-lause puuttuu. Jypeli-pelien projektimalleissa ovat vakiona seuraavat using-lauseet:
     using System;
     using Jypeli;
     using Jypeli.Widgets;
     using Jypeli.Assets;
    

Peli.Aliohjelma(): not all code paths return a value

Aliohjelmalle on määritelty paluuarvo, mutta se ei palauta mitään (eli return-lause puuttuu).

Seuraavassa aliohjelmassa paluuarvoksi on määritelty PhysicsObject, mutta aliohjelma ei palauta mitään arvoa.

PhysicsObject LuoPallo()
{
    PhysicsObject pallo = new PhysicsObject(50.0, 50.0, Shape.Circle);
}

Tällöin Visual Studio antaa virheilmoituksen.

Jos pallo halutaan palauttaa aliohjelmasta, niin aliohjelmaa pitää korjata seuraavasti.

PhysicsObject LuoPallo()
{
    PhysicsObject pallo = new PhysicsObject(50.0, 50.0, Shape.Circle);
    return pallo;
}

Aliohjelman paluuarvo on void, mutta return palauttaa jotakin

Viesti:

Since 'Peli.LuoPallo()' returns void, a return keyword must not be followed by an object expression

Tässä aliohjelman LuoPallo paluuarvoksi on määritelty void, mutta siinä yritetään kuitenkin palauttaa arvo:

void LuoPallo()
{
   PhysicsObject pallo = new PhysicsObject( 50.0, 50.0, Shape.Circle);
   return pallo;
}

Jos tässä halutaan palauttaa muuttuja pallo, pitää aliohjelman paluuarvon tyypiksi määritellä pallon tyyppi eli PhysicsObject.

PhysicsObject LuoPallo()
{
   PhysicsObject pallo = new PhysicsObject( 50.0, 50.0, Shape.Circle);
   return pallo;
}

Muuttujaa ei ole olemassa nykyisessä kontekstissa

Viesti:

The name 'massa' does not exist in the current context

Seuraavassa koodinpätkässä käytetään muuttujaa nimeltä massa, mutta tuota muuttujaa ei ole esitelty missään.

Jokainen muuttuja, jota ohjelmassa käytetään, tulee esitellä jossakin. Esittely tarkoittaa, että jollakin rivillä kirjoitetaan muuttujan tyyppi sekä nimi seuraavasti:

double massa;

Samalla rivillä esittelyn kanssa voi myös sijoittaa muuttujalle alkuarvon:

double massa = 100.0;

Niinpä äskeisen koodin virhe voidaan korjata kertomalla muuttujan massa tyyppi (tyyppi on double eli desimaaliluku) siinä missä tuo muuttuja ensimmäisen kerran otetaan käyttöön:

Jos muuttuja esitellään aliohjelmassa, se pitää esitellä ennen sen käyttöä. Jos muuttujaa tarvitaan useammassa aliohjelmassa, pitää se esitellä luokan sisällä:

public class Peli : PhysicsGame
{
    double massa;

    protected override void Begin()
    {
        massa = 100.0;
        PhysicsObject pallo = new PhysicsObject( 50.0, 50.0, Shape.Circle );
        pallo.Mass = massa;
        TulostaMassa();
    }

    void TulostaMassa()
    {
        MessageDisplay.Add( "Massa on " + massa );
    }
}

Puolipiste puuttuu

Viesti:

C# ja moni muu kieli vaatii puolipisteen (;) jokaisen lauseen loppuun. Visual Studio osaa kertoa, mistä kohtaa koodia puolipiste puuttuu. Alussa puolipisteet unohtuu helposti, mutta niitä kyllä oppii laittamaan.

Visual Studiokaan ei ole erehtymätön, ja ehdottaa puolipisteiden laittamista joskus sinne minne se ei kuulu. Esimerkiksi jos olet kirjoittamassa aliohjelman esittelyriviä, niin VS:n mielestä aliohjelman nimen perään kuuluisi puolipiste.

Mutta oikeastihan siihen kuuluu kaarisulut, ja sitten aaltosulut.

Muuttuja on jo määritelty

Viesti:

A local variable named 'massa' is already defined in this scope

Muuttuja ei tule esitellä kuin kerran. Jos saman niminen muuttuja on esitelty kahteen kertaan samassa koodilohkossa (esimerkiksi samassa aliohjelmassa), jää epäselväksi kumpaa muuttujaa oikein pitäisi käyttää.

Huomaa, että samanniminen muuttuja voi olla määriteltynä eri lohkossa (esimerkiksi luokan sisällä ja aliohjelman sisällä):

public class Peli : PhysicsGame
{
    double massa = 50.0;

    protected override void Begin()
    {
        double massa = 100.0;
        PhysicsObject pallo = new PhysicsObject(50.0, 50.0, Shape.Circle);
        pallo.Mass = massa;
    }
}

Kun aliohjelmassa käytetään muuttujaa massa, viittaa se sisemmässä lohkossa määriteltyyn muuttujaan, tässä tapauksessa aliohjelman sisällä määriteltyyn muuttujaan. Tällaista tilannetta tulisi yleensä välttää, sillä silloin tulee helposti viitattua väärään muuttujaan kuin oli tarkoitus.

Aaltosulku puuttuu

} expected

Tämä voi johtua siitä, että oikea aaltosulku (}) on jäänyt kirjoittamatta tai siitä että ennen aaltosulkua on virheellistä koodia. Seuraavassa esimerkissä on kirjoitettu toinen aliohjelma, mutta se onkin lipsahtanut aliohjelman Begin sisälle:

public class Peli : PhysicsGame
{
    double massa = 50.0;

    protected override void Begin()
    {
        double massa = 100.0;
        PhysicsObject pallo = new PhysicsObject(50.0, 50.0, Shape.Circle);
        pallo.Mass = massa;

    void TulostaMassa()
    {
    }
    }
}

Jos sulkumerkkien hahmottaminen tuntuu hankalalta, kannattaa viedä kursori toisen sulkumerkin viereen. Tällöin Visual Studio värittää tämän ja sitä vastaavan sulun. Seuraavassa kuvassa erottuu selvästi Begin-aliohjelman aaltosulut:

http://kurssit.it.jyu.fi/npo/2010/luentomateriaali/www/sulut.gif

Nimiavaruus ei suoraan sisällä attribuutteja tai aliohjelmia

Viesti:

A namespace does not directly contain members such as fields or methods

C#-kielessä kooditiedostossa on tyypillisesti määritelty nimiavaruus:

namespace Peli
{
}

Ja sen sisällä luokka:

namespace Peli
{
    public class Peli : PhysicsGame
    {
    }
}

Nimiavaruudet ovat hyödyllisiä isommissa projekteissa, mutta tämän kurssin peleissä niitä ei käytetä. Oleellista tässä on se, että C# ei salli aliohjelmien ja muuttujien kirjoittamista suoraan nimiavaruuden sisään, vaan ne tulee kirjoittaa luokan sisään. Seuraavassa esimerkissä aliohjelma on lipsahtanut luokan ulkopuolelle:

Kun kursorin vie luokan aloittavan tai lopettavan aaltosulun viereen, Visual Studio esittää nuo aaltosulut eri värillä, jolloin on helpompi kirjoittaa aliohjelma oikeaan kohtaan:

Saavuttamatonta koodia havaittu

Viesti:

Unreachable code detected

Tämä virhe tarkoittaa, että jotkut aliohjelman lauseista eivät voi koskaan tulla suoritettavaksi. Esimerkiksi seuraavassa koodissa pallon x-koordinaattiin sijoitetaan arvo, mutta koska sitä edeltävä lause on return-lause, tuohon lauseeseen ei koskaan päästä. return-lausehan palaa samantien pois aliohjelmasta!

Tämä saadaan kuntoon tekemällä tarvittavat sijoitukset ennen paluuta:

Attachments