Laden...

C#: Konkreten Typ von einer List<object> ermitteln?

Erstellt von MillionsterNutzer vor 15 Jahren Letzter Beitrag vor 15 Jahren 8.982 Views
M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 15 Jahren
C#: Konkreten Typ von einer List<object> ermitteln?

Hi!

Habe eine Funktion bei der ich als Parameter ganz abstrakt eine generische Liste vom Typ List<object> bekomme. Nun muss ich innerhalb meiner Funktion wissen von was für einem Typ die Liste denn nun genau ist.

Der einzige weg der mir hierzu einfällt ist wohl

Type t = objectListe[0].GetType();

Allerdings scheint mir das alles andere als eine elegante Lösung zu sein. Gibts da ne Möglichkeit direkt den Typ der generischen Liste zu ermitteln, ohne dabei wie oben die die darin enthaltenen Elemente prüfen zu müssen?

Grüße

M
205 Beiträge seit 2008
vor 15 Jahren

ist dir vorab bekannt welche typen die liste binhalten kann? wenn ja gehts einfach mit:


        static void Main(string[] args)
        {
            TextBox t = new TextBox();

            foo(t);
        }

        static void foo(object o)
        {
            if (o is TextBox)  // <-
                Console.WriteLine("Text");
        }

ansonsten spricht ja nichts gegen deine lösung über reflection.

0
767 Beiträge seit 2005
vor 15 Jahren

Wenn du List<object> hast wird dir keine Reflection der Welt sagen können, welchen Typs die enthaltenen Elemente sind. Da könnten ja Personen, Äpfel und ints gemischt drinn sein. Wenns geht, mach das <object> bereits als Typparameter, dann sparst du dir die Abfrage komplett.

loop:
btst #6,$bfe001
bne.s loop
rts

Gelöschter Account
vor 15 Jahren

Habe eine Funktion bei der ich als Parameter ganz abstrakt eine generische Liste vom Typ List<object> bekomme.

in c# sind es methoden. und nebenbei bemerkt ist es ganz abstrakt ein großes großes dont, eine liste von objekten zu nehmen. das sollte man unter allen erdenklichen möglichkeiten vermeiden.

wenn du also eine kontrolle darüber hast, dann überlege, ob du nicht doch irgendeine basisklasse findest.

0
767 Beiträge seit 2005
vor 15 Jahren

abgesehen davon könntest du den Typ nicht rausfinden, wenn die Liste leer ist...

loop:
btst #6,$bfe001
bne.s loop
rts

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 15 Jahren

Hi!

Also vielleicht war mein erster Post doch etwas zu abstrakt. In meinem Fall geht es um eine Basisklasse von denen mehrere unterschiedlicher geerbte Klassen vorhanden sind.

Man könnte also sagen ich habe eine Basisklasse GeometrischeForm von der z.B. Quadrad und Dreieck abgeleitet sind.

Meine Methode hat nun den Parameter List<GeometrischeForm>, wobei ich jedoch sicher weiß das in der Liste nur Objekte einer Art vorkommen können, also nur Dreiecke oder nur Quadrate. Aber wie bekomme ich nun sauber raus, was denn nun genau drin steckt?

@markus.bodlos:
Den Gedanken von dir hatte ich auch schon, aber leider sind das wirklich jede Menge abgeleiteter Klassen, wenn ich jede einzeln abfragen würde... das wäre echt ungeschickt.

@0815Coder:
Mein Gefühl sagt mir du hast recht, aber ich will es eben nicht so recht glauben 😕. Meine Liste ist doch extra typisiert, dann müsste man doch auch den Typ herausbekommen, oder?

(Puh, ihr schreibt zu schnell...)

@JAck30lena:
(Sorry wegen den Methoden 🙂 - Leider geht es nicht anders, ich MUSS auf gegebenen Code aufbauen. Glaub mir: Ich würde es anders machen, wenn ich es könnte.

@0815Coder:
Wenn die Liste doch ursprünglich als

List<Dreieck> eineListe;

definiert wurde, dann müsste man eben diesen Dreiecks-Typ doch herausbekommen, evtl. sogar wenn sie noch leer wäre, oder?

Grüße

915 Beiträge seit 2006
vor 15 Jahren

Hrm, es ist Freitag und ich sitze vielleicht auf dem Schlauch aber wo ist das Problem?



List<GeometrischeForm > formList = new List<GeometrischeForm >();

Dreieck[] listDreiecke = formList.FindAll(delegate(GeometrischeForm geoform) { return geoform is Dreieck; });

Quadrat[] listQuadrate = formList.FindAll(delegate(GeometrischeForm geoform) { return geoform is Quadrat; });


Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

0
767 Beiträge seit 2005
vor 15 Jahren

@0815Coder:
Meine Liste ist doch extra typisiert, dann müsste man doch auch den Typ herausbekommen, oder?

ja. aber maximal bekommst du den Type == typeof(GeometrischeForm), und wenn noch so viele Dreiecke drinn sind.

@0815Coder:
Wenn die Liste doch ursprünglich als

List<Dreieck> eineListe;  

definiert wurde, dann müsste man eben diesen Dreiecks-Typ doch herausbekommen, evtl. sogar wenn sie noch leer wäre, oder?

ja, dann bekommst du typeof(Dreieck), genauso wie du bei der List<GeometrischeForm> eben typeof(GeometrischeForm) bekommst.

loop:
btst #6,$bfe001
bne.s loop
rts

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 15 Jahren

Mal etwas ausführlicher:


//Diese Methode gibt es noch in zig Varianten mit unterschiedlichen geometrischen Formen
private void AufrufenderCode() 
{

//...

List<Dreieck> dreieckListe = new List<Dreieck>();
dreieckListe.Add(new Dreieck());
dreieckListe.Add(new Dreieck());
dreieckListe.Add(new Dreieck());

DoSomething(dreieckListe);

//...

}

public void DoSomething(List<GeometrischeForm> dieListe)
{

//...

Type t = dieListe[0].GetType(); //TODO: Das muss doch auch anders gehen!?!?!?!?

//...

}

Hmm, wäre das jetzt etwas verständlicher?

1.665 Beiträge seit 2006
vor 15 Jahren
Type listenTyp = deineListe.GetGenericTypeDefinition();
4.939 Beiträge seit 2008
vor 15 Jahren
public void DoSomething(List<GeometrischeForm> dieListe)  
{  
//...  
  
Type t = dieListe[0].GetType(); //TODO: Das muss doch auch anders gehen!?!?!?!?  
  
//...  
}  

Wie soll es denn einfacher gehen, ohne auf die Listen-Elemente zu schauen?

Wofür benötigst du überhaupt den konkreten Datentyp innerhalb der Liste?
Wenn du spezielle Aktionen benötigst, so solltest du diese mittels virtueller Methoden der Basisklasse definieren und dann entsprechend in den abgeleiteten Klassen überschreiben.

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 15 Jahren

Hi!

Also ich glaub ich habs:

public void DoSomething(List<GeometrischeForm> dieListe)
{

//...

Type t = dieListe[0].GetType();

Type t1 = dieListe.GetType(); //Liefert mir List<Dreieck>
Type t2 = t1.GetGenericArguments()[0]; //Liefert mir Dreieck => Das will ich!
Type t3 = t1.GetGenericTypeDefinition(); //Liefert mir List<Dreieck>

//...

}

Allerdings muss ich zugeben, dass das ganze immer noch nicht elegant ist. Naja, manchmal muss man auch verlieren können 🙂

Trotzdem: DANKE AN ALLE!!!

Grüße

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo MillionsterNutzer,

wenn der Parametertyp List<GeometrischeForm> ist, dann kannst du nur Objekte vom Typ List<GeometrischeForm> oder vom Typ einer Unterklassen davon übergeben. Nun ist aber List<Dreieck> keine Unterklasse von List<GeometrischeForm> und zwar auch dann nicht, wenn Dreieck eine Unterklasse von GeometrischeForm ist. Die Frage nach dem Typ der Liste stellt sich also gar nicht. Die Liste ist immer von Typ List<GeometrischeForm>. Insofern würde ich auch die folgende Aussage bezweifeln:

Type t1 = dieListe.GetType(); //Liefert mir List<Dreieck>  

Wenn du nun Listen hast, die zwar vom Typ List<GeometrischeForm> sind, aber nur Dreiecke enthalten, dann ist die einzige Chance das festzustellen, den Typ aller Elemente einzeln zu prüfen. Ob du das schön findest oder auch nicht.

Den Typ der Element prüft man sinnvollerweise nicht per GetType, sondern mit `dieListe _ is Dreieck[/tt].

herbivore