Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
g1ml1
Člen
Avatar
g1ml1:3.1.2014 19:26

Zdravím,
mám dvě třídy

class BasicInfo
class AccidentInfo:BasicInfo

takže můžu udělat:

BasicInfo bInfo;
AccidentInfo aInfo = new AccidentInfo();
bInfo = aInfo;

ale potřeboval bych udělat:

List<BasicInfo> basicInfoes;
List<AccidentInfo> accidentInfoes = new List<AccidentInfo>();
basicInfoes = (List<BasicInfo>)accidentInfoes;

Chtěl bych totiž použít metodu, která je napsaná pro List<BasicInfo> i pro List<AccidentInfo> (mění se jen společné property)

Editováno 3.1.2014 19:26
 
Odpovědět
3.1.2014 19:26
Avatar
coells
Tvůrce
Avatar
Odpovídá na g1ml1
coells:3.1.2014 19:43

To nemůžeš udělat kvůli typové varianci. Řekněme, že máš následující typy:

class BasicInfo {}
class AccidentInfo : BasicInfo {}
class AdditionalInfo : BasicInfo {}

List<BasicInfo> basics;
List<AccidentInfo> accidents;

Pokud bys přetypoval List<AccidentInfo> na List<BasicInfo>, mohl bys do něj vložit typ AdditionalInfo, jenže ten nedědí od AccidentInfo, ale pouze od BasicInfo.

Takže List<T> je invariantní a podobné přetypování je zakázané. Musíš to řešit přes generika:

void Add<T>(List<T> list, T item) where T : BasicInfo
{
  list.add(item);
}
 
Nahoru Odpovědět
3.1.2014 19:43
Avatar
g1ml1
Člen
Avatar
Odpovídá na coells
g1ml1:3.1.2014 20:24

Zkusil jsem to předělat na generiku:

private List<T> AddEventClassTextAndIcon<T>(List<T> basicInfoes) where T:BasicInfo
{
    T temp;
    for (int i = 0; i < basicInfoes.Count; i++)
    {
        temp = basicInfoes[i];
        temp.EventClassText = updateClassesText[temp.EventClassId - 1];
        switch (temp.EventClassId)
        {
          //todo
        }

    }

    return basicInfoes;
}

a tohle projde:

AddEventClassTextAndIcon<AccidentInfo>(new List<AccidentInfo>());

ale když tam pošlu List z IEnumerable tak to nefunguje:

AddEventClassTextAndIcon<AccidentInfo>(query.ToList());
Editováno 3.1.2014 20:25
 
Nahoru Odpovědět
3.1.2014 20:24
Avatar
coells
Tvůrce
Avatar
Odpovídá na g1ml1
coells:3.1.2014 20:32

No protože musíš opět dodržet typovou varianci. Máš tam bordel v typech. Stačí, když využiješ varianci:

AddEventClassTextAndIcon(new List<AccidentInfo>());

IEnumerable<BasicInfo> query = ...;
AddEventClassTextAndIcon(query.ToList());

A pokud napíšeš tu svoji metodu korektně přes IEnumerable<T> místo List<T>, nemusíš dokonce ani volat metodu ToList().

 
Nahoru Odpovědět
3.1.2014 20:32
Avatar
g1ml1
Člen
Avatar
Odpovídá na coells
g1ml1:3.1.2014 20:49

No to IEnumerable vrací AccidenInfo a ToList() volám abych odpálil dotaz do db.

var query = db.Database.SqlQuery<AccidentInfo>(sqlQueriesForAccidents[0], date.Date);

return AddEventClassTextAndIcon<AccidentInfo>(query.ToList());
 
Nahoru Odpovědět
3.1.2014 20:49
Avatar
coells
Tvůrce
Avatar
Odpovídá na g1ml1
coells:3.1.2014 20:57

Protože tam máš bordel v typech, už jsem ti to psal. Alespoň si přečti, jakou chybu píše kompilátor.

Tohle je plně funkční kód:

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<B> b = new B[10];
        List<B> result = Add(b.ToList(), new B());
    }

    static List<T> Add<T>(List<T> list, T item) where T : A
    {
        list.Add(item);
        return list;
    }
}

class A
{
}

class B : A
{
}
 
Nahoru Odpovědět
3.1.2014 20:57
Avatar
g1ml1
Člen
Avatar
Odpovídá na coells
g1ml1:3.1.2014 21:11

Já to prostě nevidím a kompilátor píše pořád to stejné jako na začátku.

Cannot implicitly convert type 'System.Collections.Generic.List<DopDat.Models.AccidentInfo>' to 'System.Collections.Generic.List<DopDat.Models.BasicInfo>'

edit:
Ok, už to mám, jsem debil.
Děkuji za pomoc

Editováno 3.1.2014 21:15
 
Nahoru Odpovědět
3.1.2014 21:11
Avatar
coells
Tvůrce
Avatar
Odpovídá na g1ml1
coells:3.1.2014 21:17

:-D V tom případě hádám, že chyba bude tady: return AddEventClassTex­tAndIcon<Acci­dentInfo>(que­ry.ToList());

Neboli se snažíš vracet instanci typu List<AccidentInfo> a návratová hodnota je typu List<BasicInfo>.

 
Nahoru Odpovědět
3.1.2014 21:17
Avatar
g1ml1
Člen
Avatar
Odpovídá na coells
g1ml1:3.1.2014 21:21

Přesně tak, nedošlo mi, že ten error se vztahuje k tomu return, pořad jsem si myslel, že je problém na vstupu té metody. :-)

 
Nahoru Odpovědět
3.1.2014 21:21
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.