Laden...

Felder mit Typ einer Klasse aus PropertyInfos filtern

Erstellt von MKonrad vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.319 Views
M
MKonrad Themenstarter:in
33 Beiträge seit 2007
vor 15 Jahren
Felder mit Typ einer Klasse aus PropertyInfos filtern

Hi Leute,

hab da mal wieder eine Frage und es wäre super, wenn ihr mir helfen könntet.

Ich habe eine Methode geschrieben, die mir für ein übergebenes Objekt alle PropertyInfos ausliest und in einer List<PropertyInfo> speichert und diese zurückgibt. Da die Objekte aber teilweise Felder enthalten, die vom Typ einer anderen Klasse meines Projekts sind, suche ich nach einer Möglichkeit sie komfortabel herauszufiltern.

Ich mache das momentan so:



List<PropertyInfo> ListPropertyInfo = new List<PropertyInfo>();

foreach (PropertyInfo pi in obj.GetType().GetProperties())
{
                if ((pi.PropertyType != typeof(Angebot)) &
                    (pi.PropertyType != typeof(Lieferant)) &
                    {
                        ListPropertyInfo.Add(pi);
                    }
}


Ich prüfe also alle möglichen Klassen meines Projekts ab, halte das aber für keine schöne Lösung.

So was wie


pi.PropertyType.typeof(class)

funktioniert leider nicht, um alle Klassen herauszufiltern.

Habt ihr eine Idee, wie man das geschickt lösen kann?

Danke im voraus.

Gruß,
MKonrad

I
86 Beiträge seit 2006
vor 15 Jahren

Hi!

Ich weiß zwar nicht genau, wofür du das brauchst, aber du kannst z.B. alle Typen der aktuellen Assembly laden (wenn dein Projekt nur aus einer Assembly besteht), um die hardgecodeten If-Abfragen zu vermeiden.

public static PropertyInfo[] GetForeignProperties(object obj)
{
	List<PropertyInfo> properties = new List<PropertyInfo>();
	Assembly currentAssembly = Assembly.GetExecutingAssembly();
	Type[] ownTypes = currentAssembly.GetTypes();

	foreach (PropertyInfo pi in obj.GetType().GetProperties())
	{
		if (!ownTypes.Contains(pi.PropertyType))
			properties.Add(pi);
	}

	return properties.ToArray();
}

Lg oli

2.891 Beiträge seit 2004
vor 15 Jahren

Hallo MKonrad,

also mir fallen spontan zwei Dinge auf: Erstens, du könntest die Bedingung der if-Abfrage in eine extra Methode auslagern (zum Thema "sieht nicht schön aus"). Zweitens finde ich die "Blacklist" unvorteilhaft. Also du filterst (hardcoded!) bestimmte Werte aus. Besser wäre, wenn du - statt unerlaubte Werte wegzuschmeißen - nur erlaubte Werte in die Liste aufnimmst.

Eine Möglichkeit wäre auch, nach Namespaces zu filtern.
Interessant wäre aber, was du "wirklich" machen möchtest.

Gruß,
dN!3L

P.S.: Um noch etwas haarspaltend zu sein:

alle PropertyInfos ausliest ... aber teilweise Felder enthalten

Properties sind KEINE Felder. Da besteht ein großer Unterschied.

M
MKonrad Themenstarter:in
33 Beiträge seit 2007
vor 15 Jahren

Hi,

danke für die Antworten erstmal.

Also diese Methode, die mir die PropertyInfos zurückliefert setze ich für verschiedene Dinge ein. Zum einen, um Dialogfelder mit den Werten der PropertyInfos der Objekte zu füllen und auch z.B. als Suchfunktion. Ich fülle damit eine ComboBox, die mir alle Feldnamen der Klasse "Mitarbeiter" ausgibt (z.B. "Vorname", "Telefon" etc.). Dann wähle ich das Feld aus, in dem ich suchen möchte und gebe in das Eingabefeld einen Suchbegriff ein. Die ListBox, die die Mitarbeiter anzeigt, wird dann entsprechend dem Suchbegriff gefiltert, ähnlich wie bei diversen Mailprogrammen (vgl. Thunderbird).

Gibt es denn keine Möglichkeit alle Klassennamen meines Namespace in nen Array zu schreiben? Das könnte ich dann mit den Namen der PropertyInfos vergleichen und entsprechend filtern. Ich möchte eben ungerne die Namen der Klassen hardcoded an dieser Stelle einfügen, denn dann muss ich die ja später bei Hinzufügen einer neuen Klasse mühsam einfügen.

Danke für den Tip mit der Whitelist. Ich werde in der Methode einfach nur bestimmte Typen die ich brauche zulassen und nicht Klassen ausschließen. Trotzdem wäre eine Möglichkeit, alle Klassennamen auszugeben sehr interessant.

Habt ihr da ne Idee?

Gruß,
MKonrad

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo MKonrad,

Gibt es denn keine Möglichkeit alle Klassennamen meines Namespace in nen Array zu schreiben?

liest du eigentlich auch die Antworten?

herbivore

M
MKonrad Themenstarter:in
33 Beiträge seit 2007
vor 15 Jahren

Hallo herbivore,

ja das tue ich. Meinst Du damit die Typen der aktuellen Assembly oder habe ich was übersehen? Das sind aber doch mehr als nur die Klassentypen oder nicht? Ich wollte eigentlich nur Typ Klasse "Kunde", Typ Klasse "Mitarbeiter" etc. ausgegeben haben.

Ich habe mittlerweile ein Typ-Array mit den Typen die ich brauche erstellt und filtere dann die PropertyInfos entsprechend aus. Funktioniert wunderbar.

Verstehe leider nicht ganz, was ich nicht gelesen haben sollte. Ich habe aber auch noch nie mit Assemblies gearbeitet und von daher könnte das Problem kommen.

Gruß,
MKonrad

2.891 Beiträge seit 2004
vor 15 Jahren

Hallo MKonrad,

Meinst Du damit die Typen der aktuellen Assembly oder habe ich was übersehen? Das sind aber doch mehr als nur die Klassentypen oder nicht?

Irgendwie scheinst du begrifflich auch noch nicht ganz im Thema zu sein...
Du hast also schon Assembly.GetTypes() ausprobiert(?) Und da bekommst du auch Typenobjekte, die nicht Klassen sind (sondern Schnittstellen, Structs, etc.)(?) Soweit stimmt das.
Aber du kannst doch an einem Typenobjekt erfragen, worum es sich handelt (bzw. ob es eine Klasse ist). Dann ergibt sich beim Erstellen des Arrays (btw: nimm eine [generische] Liste, die hat z.B. auch Contains(value)) doch das gleiche Vorgehen, wie bisher: Über alle Typen der Assembly iterieren und dann nur Typen in die Liste aufnehmen, die Klassen repräsentieren (und in best. Namespace liegen etc.)

Mehr Infos gibt's auch in [Artikel] Reflection und Metaprogrammierung

Gruß,
dN!3L

M
MKonrad Themenstarter:in
33 Beiträge seit 2007
vor 15 Jahren

Hi dN!3L,

danke für die Antwort erstmal.

Dein Tip mit der Assembly.GetTypes() ist ja schon gut, aber ich suche ja nach einer Möglichkeit, nur die Klassen aus der Liste herauszufiltern, ohne den konkreten Klassennamen angeben zu müssen. Einfach feststellen, ob es sich um eine Klasse handelt, mehr nicht. typeof(class) funktioniert ja leider nicht.

Gruß,
MKonrad

2.891 Beiträge seit 2004
vor 15 Jahren

Hallo MKonrad,

oh oh, du solltest dich dringend nochmal damit beschäftigen, was so ein Type-Objekt eigentlich ist bzw. repräsentiert.

Einfach feststellen, ob es sich um eine Klasse handelt, mehr nicht. typeof(class) funktioniert ja leider nicht.

Siehe Type.IsClass.

Gruß,
dN!3L

M
MKonrad Themenstarter:in
33 Beiträge seit 2007
vor 15 Jahren

Danke, dass habe ich gesucht 😃