Az objektumhivatkozás nincs beállítva semmilyen objektumpéldányra. Mi a probléma?
Van efy feladat amiben egy musorlista van. egy sor áll egy sorszámból, egy óra , percből egy előadóból és a zzenéből.
A adatok 2 dologgal vannak elválasta 'sóközzel' és ':'-tal. Az utóbbi egyedül az előadó és a zene között van. Tehát egy sor így néz ki:
1 5 3 Deep Purple:Bad Attitude
3 4 33 Omega:A szamuzott
Beolvasással van szóval probléma. Előszőr megpróbáltam úgy, hogy beolvasom egy sorba a egészet majd ezt a stringet fel splittelem ':' karakterenként 1-1 külön stringbe, majd az első stringet 'space'-enként splittelem. Ezzel csak az volt a probléma, hogy nem mindenhol 1 szóból áll az előadó neve. Ezzel a másik megoldásban, amit a ghostbinre is feltettem, viszont az a probléma, hogy a kérdésben is leírt error-t dobja és "nem tudom" mért. A gopndja Music nevű változóval van, ugyanis ha kitörlöm arra vonatkozó dolgokat (pl a kontstruktorban a song, valamint az artist és zene változókat ahol splittelek+property stb) , akkor gond nélkül kiírja az adatokat. Sóval mit kellen módosítanom/átírnom, csinálnom stb, hogy jó legyen?
Ez a kód nem csinál ilyen hibát, amit írsz.
Egyébként kicsit átgondolhatnád ezt az osztályszerkezetet, mert borzasztó zagyvaság az egész.
H-h nem dob ilyen hibát? nekem a első ':'-nál (artist) spiltelésnél kiírja, hogy System.NullReferenceException: 'Az objektumhivatkozás nincs beállítva semmilyen objektumpéldányra.'.
A válaszod 2.résére térve.Kifejtenéd bővebben? Mire gondolsz, mit javasolsz, mit csináljak másképp ezentúl (ugyanis a kódjaim nagy részének hasonló serkezete van)
Amit most csinál a programod, az az, hogy kettesével olvassa a sorokat, ami nyilván nem jó:
Musorlista.Add(new Musorlista(sr.ReadLine(), sr.ReadLine()));
Az első apraméterhez beolvasol egy sort, a másodikhoz beolvasol még egyet. Emiatt ha páratlan számú sor van a fájlban, akkor a fájl végére érve az első paraméternek még átad egy sort, a másodikra viszont a fájl végére ér, és nullt ad át.
A feladat megoldását ott kéne kezdeni, hogy egy ÉRTELMES adatszerkezetet találsz ki hozzá. Ez, hogy vegyesen vannak space-ekkel, meg kettősponttal elválasztva az adatblokkok, főleg hogy bizonyos adatok tartalmazhatnak space-t, vállalhatatlan, és közel kezelhetetlen. Legyen egy egységes elválasztókarakter, ami az összes adatblokkot elválasztja. Pl pontosvessző:
1;5;3;Deep Purple;Bad Attitude
3;4;33;Omega;A szamuzott
És így máris egy sokkal könnyebben kezelhető adatállományt kapsz (amit egyébként CSV fájlnak hívnak)
A StreamReaderrel kapcsolatos problémákat már leírták, nem ismételném meg, de ezentúl is elég nagy katyvasz van az adatszerkezeteid és osztályaid kapcsán.
Először is van egy ilyen adatszerkezeted:
Műsorlista:class
id:int
hossz:TimeSpan
music:string[2]
Tehát azt mondod, hogy egy műsorlistának van egy azonosítója, hossza és "mjuzikja", ami két szöveg.
Hát nem tudom, én ilyen műsorlistát még nem láttam.
Felénk egy műsorlista dalokból áll.
A másik, mi az hogy music:string[2]? Egy zene az két stringből áll? Nevezd nevén az adattogokat, névtelen tömbindexekkel bohóckodni horrorisztikusan nehézkes lesz.
Sokkal értelmesebb lenne valami olyasmi szerkezet, hogy:
Műsorlista:class
Dalok:List<Dal>
TeljesHossz:TimeSpan
Dal:class
Előadó:string
Cím:string
Hossz:TimeSpan
A másik nagy probléma, hogy a Reader osztályod teljes logikája a konstruktorban van. A konstruktor dolga, hogy létrehozza az adatszerkezetet és beállítsa a kezdeti értékeket. Üzleti logikát nem érdemes beleírni, mert nem számít rá senki.
Megintcsak sokkal szebb lenne úgy megoldani, hogy:
Reader:class
Reader()
Read(path:string):Műsorlista
a music nevű string azért hívják így muivel nem tudtam milyen nevet adjak egy olyan stringnek ami tartalmazza mind a előadót mint a zeneszám címét, az id meg nem a zeneszám azonosítója, hanem a rádiójé (így van a feladatban, túl sok értelmét én se látom, hogy minek, de még magukat a résfeladatokat nem olvastam el, hogy lássam okát). és aért van ez stringben, mivel utánna még ezt a stringet akarom sét splitelni ':' alapján, aminek elsőrésze a előadó (artist), másik fele pedig maga a zneszám, ettől függetlenül tudom, hogy lehett volna úgy, hogy a music nevű változó nem egy sima string hanem egy tömb.
Az utolsó résszel kapcsolatban gondolom arra gondolsz, hogy a konstruktorba kérjem be az útvonalat. Igazából különbséget nem látok különbséget ha úgy csinálom vagy így(azon kívül, hogy magát az útvonalat ott kell megadni ahol meghívom a konstruktor (/példányosítok) ha nem tévedek), de ha másoknak úgy átláthatóbb, akkor rendben.
Hogy jobban értsétek/lássátáok a feladatot egyébként a 2005 októberi (emelt)-ről van szó
1.)
public int Id { get => id; set => id = value; }
Ezekre nem lenne egyszerűbb auto-property?
Valahogy igy: public int Id{ get; set; }
2.)
Ha már StreamReader-t használsz, olvasd el a dokumentációját, using-al érdemes használni.
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
3.) Ez igy ronda: string[] music=new string[2];
Kételemű tömb helyett inkább használj két string adattagot.
4.) Itt az adatok-ot háromszor is splitteled, ez csak felesleges erőforráshasználat a programtól.
Id = int.Parse(adatok.Split(' ')[0]);
int hour= int.Parse(adatok.Split(' ')[1]);
int minute= int.Parse(adatok.Split(' ')[2]);
Az adatok.Split(' ')-et tedd ki egy változóba.
A song-ot is hasonlóképpen kellene:
string artist = song.Split(':')[0];
string track = song.Split(':')[1];
5.)
Miért van a TimeSpan hossznak default értéke, ha úgyis mindig felülírod?
TimeSpan hossz=new TimeSpan(0,0,0);
Igazából az egész kód elférne 15-20 sorban, és szebb is lenne sokkal!
Nagyjából beleraktam a módosításotokat amikat javasoltatok ("csökkentettem" a splittelések számát, auto property, streamreader rész), de még mindig az lenne a problémám miként daraboljam úgy, hogy mind az előadó, mind a zeneszám szempontjából jó legyen. Először splitteltem ':' alapján, hogy a zeneszám címe aminél van olyan zeneszám ami több szóból áll az mindenképp egybe maradjon(mivel, hogy azok is szóköökkel vannak elválasztva így én azt gondolom szóköz alapján nem splitelhetek elsőnek). Így lesz egy 'bal oldal' (nem volt jobb ötletem névválasztás tekintetében mivel ez a rész tartalmazza a rádió azonosítóját és a zeneszám hosszát is), és egy jobb, ami maga a zeneszám. Majd a splittelés minimális szinten tartása végett a bal oldal x db-szor való feldarabolása hellyett, 1x tettem meg de (szóközönként) az elemeit egy tömb-be téve.(id, óra,perc->de az utóbbi 2-t ismételten timespanbe). Sóval összességében nem haladtam előre. A fájlszerkezetére vissatérve pedig nem soakt segítene, hogy ha egységesíthetném a darabolást, mivel dikrekt módon nem változtathatom meg a fájlt, ha meg programon belül replace-ném a ':'-kat ' '-re, akkor még mindig ott van az tényező, hogy van olyan előadó akinek a neve 2 szóból áll valakinek csak 1-ből,hasonló a zenénél is csak ott akár 4 szóból is állhat egy zene. Így erre nem tudom mi lenne a megoldás. (Ui.:a property-k meg azért néztek úgy ahogy mivel nem én írtam, hanem a VS generálta le, azzal, hogy kijelöltem a mezőket és 'quick action'-nél legeneráltattam őket).
Tehát jelenleg így néz ki a kód: [link]
(Tudom,hogy az előző linket tudtam volna szerkeszteni, de azért nem tettem, hogy a későbbi hozzászólok ne nézeneke értetlenl a kérdésre kifolyólag)
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!