Taistelen samaa virtuaalikurssin tehtävää kuin tässä: https://www.ohjelmointiputka.net/keskustelu/
Tällaisella luokalla olen nyt viimeksi yrittänyt:
class Kokoelma { private object[] arvot; public Kokoelma(int lkm) { arvot = new object[lkm]; } public double this[string indeksi] { get { try { object xx = arvot[indeksi]; double e = (double)xx; return e; } catch { return -1; } } set { try { object x = value; arvot[indeksi] = x; Console.Write("Lisätty "+indeksi+" = "+value.ToString()); } catch { Console.Write("Kokoelma on täynnä"); } } } }
Kääntäjä puskee kuitenkin erroria:
"code.cs(22,51): error CS0029: Cannot implicitly convert type `string' to `int'
code.cs(37,39): error CS0029: Cannot implicitly convert type `string' to `int'
Compilation failed: 2 error(s), 0 warnings"
Jotain en noissa tyypinmuunnoksissa tajua, kuka kertoisi, että mitä?
Jos teet taulukon (eli array eli tyyppi[]), niin sinun
a) täytyy aina määrittää taulukon lopullinen koko sitä luotaessa
b) voit viitata taulukon jäseniin ainoastaan järjestysnumerolla.
Eli johtuen kohdasta b, et voi käyttää indeksinä merkkijonoa (string). Kääntäjä kertoo tämän asian sinulle niin että se ei suostu muuttamaan merkkijonoa kokonaisluvuksi ilman että nimenomaan käsket (implisiittisesti). Eli idea on, että jos et ole implisiittisesti määritellyt haluavasi muuntaa merkkijonon kokonaisluvuksi, niin kyseessä on todennäköisesti ajatusvirhe, kuten tässä tapauksessa onkin.
Kohta a ei sinänsä ole ongelma, koska maksimikoko ilmoitetaan, mutta jos haluat käyttää taulukkoa niin sinun pitäisi pitää kirjaa siitä, montako yksikköä siitä on jo käytetty.
Voisi toisaalta sanoa, että taulukko on todennäköisesti ihan väärä tietotyyppi käyttötarkoitukseesi.
Esim. Dictionary<string,object> olisi varmasti toimivampi kuin object[]
Aloittelijalle vaan tuo Dictionary<string,object> käyttö näemmä aika haastavaa. Yritin tällaista nyt:
using System.Collections.Generic; class Kokoelma { Dictionary<string, object> arvot; public Kokoelma(int lkm) { arvot = new Dictionary<string, object>(lkm); } public double this[string indeksi] { get { try { object xx = arvot[indeksi]; double e = (double)xx; return e; } catch { return -1; } } set { try { object x = value; arvot.Add(indeksi, x); Console.Write("Lisätty "+indeksi+" = "+value.ToString()); } catch { Console.Write("Kokoelma on täynnä"); } } } }
Kääntäjä antaa edelleen erroria:
"code.cs(56,13): error CS0029: Cannot implicitly convert type `string' to `double'
code.cs(66,13): error CS0029: Cannot implicitly convert type `string' to `double'
Compilation failed: 2 error(s), 0 warnings"
Jos nyt joku voisi vielä vinkata jotain, tosi jumissa tämän kanssa....
Google -> C# string to double
double d = double.Parse(string);
Miltä riveiltä noi virheet tulee? Laittamassasi koodissa ei ole kuin 44 riviä..
Itse ongelmaan Macro kertoikin jo todennäköisen ratkaisun.
Jos nimenomaan doubleja haluat tallentaa, niin Dictionarystäkin voi tehdä <string, double>
Joudut laittamaan talteen tuon maksimikoon ja tekemään tarkistuksen itse. Dictionary ei heitä poikkeusta, vaikka laittaisit sinne enemmän tavaraa, kuin mitä olet sinne kertonut Capacity-parametrilla ajattelevasi laittaa. Capacity parametri ei rajoita maksimikokoa.
Ja mitäs toi auttaa, kun koodissa xx on objekti eikä stringi?
Tuleeko se virheilmoitus muka tuolta riviltä, jossa xx on objekti?
Mulle kääntäjä ei anna mitään virhettä tuosta koodista, joten epäilen vahvasti että nuo virheilmoitukset tulee muilta riveiltä, kuin tänne näkyviin laittamastasi.
Grez: Toi itse kirjoitettuhan on vain osa kokonaisuutta:
https://www.ohjelmointiputka.net/keskustelu/
Eli oma luokka ei kai sitten toimi yhteen kokonaisuuden kanssa...
Lisäys:
using System.Collections.Generic; class Kokoelma { Dictionary<string, string> arvot; public Kokoelma(int lkm) { arvot = new Dictionary<string, string>(); } public double this[string indeksi] { get { try { string xx = arvot[indeksi].ToString(); if(indeksi != "teksti") { double e = double.Parse(xx); return e; } else { return -1; } } catch { return -1; } } set { try { string x = value.ToString(); arvot.Add(indeksi, x); Console.Write("Lisätty "+indeksi+" = "+value.ToString()); } catch { Console.Write("Kokoelma on täynnä"); } } } }
Ja taas: "code.cs(62,13): error CS0029: Cannot implicitly convert type `string' to `double'
code.cs(72,13): error CS0029: Cannot implicitly convert type `string' to `double'
Compilation failed: 2 error(s), 0 warnings"
Tuossa linkissä siis merkitty kohta, johon oma luokka tulee. Ja siihen muuhun koodiin ei pysty vaikuttamaan, oman luokan on vastattava oikein sen laajemman koodin toimintaan.
Siksi kysyinkin, että "Miltä riveiltä noi virheet tulee?"
Niin, eli rivit joista tulee virhe on seuraavan näköisiä:
kokoelma["teksti"] = "Hei maailma!";
Miksi sitten höpisit että "mitäs toi auttaa, kun koodissa xx on objekti eikä stringi?", kun kerran itsekin tiesit, ettei se liittynyt asiaan mitenkään?
Tosin tässä tapauksessa tietenkään double.Parse("Hei maailma!") ei auttaisi hirveän pitkälle. Käännösvirheen se poistaisi, mutta ajonaikana tulisi sitten ilmoitus, ettei "Hei maailma!":aa voi muuttaa liukuluvuksi.
Jos haluat tallentaa sinne objekteja, niin ota vastaan objekteja ja tallenna ne sinne ilman muunnoksia. Nythän otat vastaan ja annat ulos vain doubleja:
public double this[string indeksi]
Eli yllä olevasta koodista jokainen double hevon kuuseen.
Thx Grez, olisi pitäny vaan johdonmukaisesti palauttaa objektia :). Kiitokset taas.
Aihe on jo aika vanha, joten et voi enää vastata siihen.