Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:29 Der er 36 kommentarer og
1 løsning

List<T> find hvilken type T er, men hvordan?

Jeg har noget kode fx. List<Customer>. Jeg har lavet en metode fx:

public T ProcessPersons<T>(string foo){
      //Jeg vil gerne kunne se at min T indholder en liste af Customer. Hvordan kan jeg se object typen Customer?
Har forsøgt med noget a la
Type a = typeof(T).GetType(); ///men får ikke 'Customer' ud i a

}

Kald af metode:

var a = ProcessPersons<List<Customer>("et eller andet argument")
Avatar billede arne_v Ekspert
21. februar 2011 - 22:37 #1
Type a = typeof(T)

?
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:42 #2
Jeg får ikke at vide at det er Customers, der ligger i listen.

Jeg vil have noget lignende:

string a = typeof(T).Name;

Hvor a giver mig "Customer". SÅ jeg ved det er customers.
Avatar billede arne_v Ekspert
21. februar 2011 - 22:48 #3
using System;

namespace E
{
    public class Program
    {
        public static void HelloWorld<T>()
        {
            Console.WriteLine(typeof(T).Name + " says hello world");
        }
        public static void Main(string[] args)
        {
            HelloWorld<int>();
            HelloWorld<string>();
            Console.ReadKey();
        }
    }
}

virker fint.
Avatar billede arne_v Ekspert
21. februar 2011 - 22:51 #4
Ah - nu tror jeg at jeg forstår.

ER det:

using System;
using System.Collections.Generic;

namespace E
{
    public class Program
    {
        public static void HelloWorld<T>()
        {
            Console.WriteLine(typeof(T).GetGenericArguments()[0].Name + " says hello world");
        }
        public static void Main(string[] args)
        {
            HelloWorld<List<int>>();
            HelloWorld<List<string>>();
            Console.ReadKey();
        }
    }
}
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:52 #5
Hmmm jo men, hvis det nu er en List<string> du sender med, hvordan kan du få "string says hello world"?

(Har ikke testet dit eksempel, men har prøvet noget lignende)
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:53 #6
Damn....sorry så ikke det var en liste... lad mig lige teste :)

Håber det også kan håndtere mit Customer objekt
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:53 #7
ahhh du lavede om på dit eksempel...så dit seneste og kunne se listen :P
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:55 #8
Jeg får en en IndexOutOfRange exception på denne:

string a = typeof (T).GetGenericArguments()[0].Name;
Avatar billede Syska Mester
21. februar 2011 - 22:56 #9
Type type = typeof(List<string>);
            Type[] genericArguments = type.GetGenericArguments();

            foreach (Type genericArgument in genericArguments)
            {
                Console.WriteLine(genericArgument.Name);
            }

Giver dig "String" som jeg tror er hvad du efterlyser.

mvh
Avatar billede arne_v Ekspert
21. februar 2011 - 22:57 #10
Og T er List<Customer> ?
Avatar billede Syska Mester
21. februar 2011 - 22:58 #11
Damm you arne :-) *heheh*
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:58 #12
Ja
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 22:59 #13
Vent fejl 40...havde ændret typen til bare en Customer...sorry...tjekker lige...
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 23:00 #14
Tak Arne...og Buzzzz

Jeg havde nogle problemer med at finde objekt typen i listen...det er godt, jeg laver generics i min fritid...
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 23:01 #15
Smid bare et svar ind...du er altid redningsmanden Arne :)
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 23:12 #16
Et hurtigt bonus spørgsmål:

Er der nogen bedre måde at spørge på om typen er en List eller array...istedet for denne:

if (typeof(T).Name == "List`1"){

}
...mon isArray() findes...
Avatar billede Syska Mester
21. februar 2011 - 23:18 #17
Type type = typeof(List<string>);
            if (type.DeclaringType == typeof(List<>).DeclaringType)
            {
                Console.WriteLine("Its a list");
            }
Avatar billede Syska Mester
21. februar 2011 - 23:20 #18
type.IsArray er en property, men en List og alt deraf er jo en List og ikke et Array, så det vil ikke løse problemet.

På den her måde er der i hvert fald ingen magic strings.
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 23:23 #19
Tak Buzz
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 23:33 #20
BUzz er du sikker på din linje?
if (type.DeclaringType == typeof(List<>).DeclaringType)

Debugger man står der 'null' i begge...dvs. null == null
Avatar billede Syska Mester
21. februar 2011 - 23:37 #21
Haha :-) Du har ret.

Dette burde virke:
if (type.GetGenericTypeDefinition() == typeof(List<>).GetGenericTypeDefinition())
            {
                Console.WriteLine(type.GetGenericTypeDefinition());
                Console.WriteLine("Its a list");
            }
Avatar billede CodingJoe Nybegynder
21. februar 2011 - 23:43 #22
Virke ikke hvis T lige pludselig er en Customer og ikke en List<Customer>

Jeg får en InvalidOperationException nu ved kald af min metode ved et Customer objekt.
Avatar billede Syska Mester
22. februar 2011 - 00:04 #23
Ja ...

Så kan du bruge: type.IsGenericTypeDefinition for at finde ud af om du skal teste på det.

mvh
Avatar billede johny Nybegynder
22. februar 2011 - 00:06 #24
Tja, der er flere måder at tjekke for list type på, men det kommer også lidt an på hvad du gerne vil finde ud af? F.eks. kunne du jo spørge ad om den implementerede IList eller IEnumerable? Eller noget i stil med:

System.Type t = obj.GetType();

return t.IsGeneric && t.GetGenericTypeDefinition() == typeof(List<>).GetGenericTypeDefinition();
Avatar billede CodingJoe Nybegynder
22. februar 2011 - 00:09 #25
Nu har jeg også et andet problem, når jeg forsøger at returnere mit Customer objekt som:

return myCustomer as T; //InvalidCastException

Det virker fint med mine List<T>
return (T)Convert.ChangeType(myCustomer.ToList(), typeof(T));
Avatar billede CodingJoe Nybegynder
22. februar 2011 - 01:03 #26
Jeg fandt ud af det... der skulle et .Single() til sidst i mit LINQ udtryk. :S
Avatar billede arne_v Ekspert
22. februar 2011 - 03:30 #27
Eksempel som analyserer både det ene og det andet:

using System;
using System.Collections;
using System.Collections.Generic;

namespace E
{
    public class Program
    {
        public static void HelloWorld<T>()
        {
            Console.WriteLine(typeof(T).Name + ":");
            if(typeof(T).IsArray)
            {
                Console.WriteLine("  array");
            }
            else if(typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(List<>))
            {
                Console.WriteLine("  generic list");
            }
            else if(typeof(IEnumerable).IsAssignableFrom(typeof(T)) ||
                    (typeof(T).IsGenericType && typeof(IEnumerable<>).IsAssignableFrom(typeof(T).GetGenericTypeDefinition())))
            {
                Console.WriteLine("  something else enumerable");
            }
            else
            {
                Console.WriteLine("  just something");
            }
        }
        public static void Main(string[] args)
        {
            HelloWorld<int>();
            HelloWorld<string>();
            HelloWorld<int[]>();
            HelloWorld<string[]>();
            HelloWorld<List<int>>();
            HelloWorld<List<string>>();
            HelloWorld<ArrayList>();
            HelloWorld<Dictionary<int, string>>();
            HelloWorld<IList<int>>();
            HelloWorld<ICollection<int>>();
            HelloWorld<IEnumerable<int>>();
            HelloWorld<IDictionary<int, string>>();
            Console.ReadKey();
        }
    }
}
Avatar billede arne_v Ekspert
22. februar 2011 - 03:31 #28
og et svar
Avatar billede CodingJoe Nybegynder
22. februar 2011 - 19:22 #29
Tak for svar Arne...jeg nominerer dig gerne til MVP, hvis du ikke allerede er det :)
Avatar billede arne_v Ekspert
22. februar 2011 - 19:44 #30
Jeg er ikke MVP. Bliver det sikkert heller aldrig.
Avatar billede Syska Mester
22. februar 2011 - 19:49 #31
Hehe, nej, jeg skulle også gerne nominere Arne_v til MVP. Men nu er der ikke penge eller noget som helst ud i det ... udover titelen. Gratis adgang til MVP Summit, men du skal selv betale Hotel og rejse.

Så MVP er bare for at blive mere kendt i IT-Samfundet ... andet synes jeg ikke rigtig det giver MVP'erne.

mvh
Avatar billede janus_007 Nybegynder
22. februar 2011 - 21:23 #32
Model View Presenter?
Avatar billede arne_v Ekspert
22. februar 2011 - 21:34 #33
Det var naturligvis on topic, men på den anden side tror jeg ikke at de vil nominere mig til at blive et kendt frontend pattern.

:-)

http://mvp.support.microsoft.com/
Avatar billede janus_007 Nybegynder
22. februar 2011 - 21:37 #34
btw.. det er faktisk ikke generics du sådan arbejder med :), det er mere en tilnærmet følelse af at bruge det magiske T, men uden rigtigt at være på, hvis du forstår :)


public T ProcessPersons<T>(string foo){

Kan lige så nemt klares med :
public object ProcessPersons(object myO, string foo)

Det giver ikke den store mening at oversætte typen i metoden og herefter gøre noget.

Hvis du har en type af Customer, lad os også sige du har et interface på den så:

public T ProcessPersons<T>(string foo) where T:ICustomer
{
...

}
Avatar billede CodingJoe Nybegynder
22. februar 2011 - 21:53 #35
Du er i hvertfald most valued professional i mine øjne... :D
Avatar billede CodingJoe Nybegynder
22. februar 2011 - 21:56 #36
@Janus

For ikke at kopiere hele min kode ind her...så valgte jeg at koge det ned til et enkelt lille problem jeg havde :)

Jeg bruger Generics og masser af Linq2Xml i min metode, som ikke er kopieret ind her...
Avatar billede janus_007 Nybegynder
22. februar 2011 - 22:44 #37
Okay... det var bare ikke lige til at se det ud fra dit eksempel, men tiptop :)
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