Avatar billede spif2001 Nybegynder
09. november 2006 - 16:12 Der er 10 kommentarer og
2 løsninger

Lave Type om til Class

Hey

Jeg sidder med en metode, der ligner det her:

public void DoIt<T>() where T : AObject, new()
{
  bla bla....
}

hvor AObject er en abstract superklasse, som mine entitets klasser alle nedarver fra.

Nu vil jeg så kalde metoden. Jeg har Type'n til den, som jeg vil kalde DoIt med, og vil gerne kalde den dynamisk på følgende facon.

DoIt<type.??>();

i stedet for eksempelvis

DoIt<MyClass>();

hvor MyClass er nedarvet fra AObject. Jeg ved på compile tidspunktet ikke hvilken klasse metoden bliver kaldt med, men jeg kan få fat i typen.

Hvordan løser jeg lige det? Eller kan det slet ikke lade sig gøre?
Avatar billede burningice Nybegynder
09. november 2006 - 20:13 #1
er det ikke bare at kalde med AObject som type?

DoIt<AObject>();
Avatar billede hacked Nybegynder
10. november 2006 - 03:07 #2
Jeg kan ikke forstå hvorfor du vil det gøre det dynamisk. Såvidt jeg ved er det heller ikke muligt. Dot virker ikke inde i krokodillenæb.
Jeg ville gøre det på burningice's måde. Efter mit hoved giver den løsning mere mening.
Avatar billede spif2001 Nybegynder
10. november 2006 - 08:48 #3
@burningice

Det kan jeg ikke, da der inde i DoIt metoden kører noget reflection og noget hiven ud af PropertyInfo oplysninger på T. De oplysninger SKAL i eksemplet være fra MyClass - det er ikke nok, at det bare er fra AObject.
Til info, er det fordi at jeg hiver alle property navne ud, og bruger dem til en SQL sætning, så jeg får et T object fyldt op med de data, der har samme navne i databasen. MyClass har f.eks. 2 propertys: ID og Age. Med reflection får jeg så fat i "MyClass", som er tabel navn og "ID" og "Age" som er kolonne navne - men disse eksisterer ikke i AObject.

@malkor
Grunden til at jeg vil gøre det dynamisk er, at når jeg er færdig, kan jeg kalde min metode DoIt, med hvilket som helst object.
Når jeg er HELT færdig, skal jeg, når jeg må implementere en ny entitets klasse, kun lave en klasse der nedarver fra AObject med attributter og tilhørende properties. Tilføje det som tabel + kolonner i databasen - og det er det! Alt anden kode er så dynamisk, at der f.eks. ikke står MyClass ét eneste sted udover i dens egen klasse - og så muligvis i en GUI - og det er der jeg vil have muligheden for at bruge type og ikke et klasse nacn ;)

Håber jeg har gjort mig forståelig. Hvis ikke så spørg endelig :)
Avatar billede burningice Nybegynder
10. november 2006 - 20:59 #4
du får nok lidt af et problem.

Det er nemt nok, via Reflection, at finde ud af hvilke SubTypes der findes. Dvs. at hvis du har B der arver fra A så kan du ved hjælp af reflection få fat i A ud fra B, men desværre ikke omvendt.

Du bliver nødt til at kalde din metode explicit med den type du i metoden vil benytte dig af. Vil du finde alle attributer på klassen B, så bliver du nødt til at give B som argument, selvom metoden f.eks. kun forventer A.

Hvis du ved ved runtime ved hvilken type metoden bliver kald med, hvorfor så ikke caste det til den rigtige type før metoden kaldes?

ie.

AObject a = System.Activator.CreateInstance("noget", "din klasse");
DoIt<a>();
Avatar billede sovsekoder Nybegynder
10. november 2006 - 21:10 #5
Eller skrive metoden som:
public void DoIt(Type t)
Avatar billede spif2001 Nybegynder
13. november 2006 - 10:06 #6
@burningice
AObject a = System.Activator.CreateInstance("noget", "din klasse");
DoIt<a>();

Ville da være rart, men jeg kan ikke proppe a ind i krokodillenæbene. Får en:

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

Når metoden hedder DoIt<T>(), skal den kaldes med klassen og ikke et object.

ie.

DoIt<MyClass>()

og ikke en instans a la

MyClass m = new MyClass();
DoIt<m>()


@sovsekoder
Duer desværre ikke pga. koden længere inde i mit datalag.
Avatar billede md_craig Nybegynder
13. november 2006 - 20:00 #7
Dit store problem er faktisk at du vil til at bruge <T> til noget som egentlig slet ikke er beregnet til...

http://en.wikipedia.org/wiki/Generic_programming
Avatar billede spif2001 Nybegynder
13. november 2006 - 20:44 #8
Hæ - ja det ser jo unægteligt sådan ud.

Har aldrig forsøgt at få et (assembly+)klassenavn ud på en dynamisk facon. Regnede heller ikke rigtig med at det kunne lade sig gøre, men tænk nu hvis..... ;)

Hvordan får jeg nu delt point ud her?

Læg svar allesammen, så prøver jeg at fordele pointene rimeligt ud - haha
Avatar billede hacked Nybegynder
13. november 2006 - 22:17 #9
Ved ikke om det også gælder mig, men her er ihvertfald et svar :)
Avatar billede burningice Nybegynder
14. november 2006 - 14:31 #10
spif2001>> hvad så med

AObject a = System.Activator.CreateInstance("noget", "din klasse");
DoIt<typeof(a)>();

Men ja, som md_craig nævner, så misbruger du lidt generics ved at gøre det her. Forslaget sovsekoder kom med er nok den mest korrekte metode.
Avatar billede burningice Nybegynder
14. november 2006 - 14:47 #11
og et svar...
Avatar billede spif2001 Nybegynder
16. november 2006 - 20:25 #12
Giver ice det meste - og da alle ikke har svaret, bliver det 10-50 til malkor og ice.

AObject a = System.Activator.CreateInstance("noget", "din klasse");
DoIt<typeof(a)>();

Kan desværre heller ikke lade sig gøre - har opgivet det nu. Er efterhånden overbevist om, at det ikke kan lade sig gøre - måske i .net 3.0? Vi får at se...  :)
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