Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Welches Objekt habe ich?
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

Welches Objekt habe ich?

beantworten | zitieren | melden

Hallo, Wie kann ich ermitteln welches Objekt ich gerade bekommen habe?

z.b. ich bekomme ein Object übergeben. Wie kann ich ermitteln ob es sich um ein String handelt?

Gab es da nicht so etwas wie InstanceOf?

Danke für die Hilfe!

Pedro
private Nachricht | Beiträge des Benutzers
Pulpapex
myCSharp.de - Member



Dabei seit:
Beiträge: 939
Herkunft: Rostock

beantworten | zitieren | melden

Du suchst wahrscheinlich den is-Operator. Entspricht dem instanceof-Operator von Java.

if(obj is ArrayList) {
}
private Nachricht | Beiträge des Benutzers
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

beantworten | zitieren | melden

Danke!

Pedro
private Nachricht | Beiträge des Benutzers
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

Welche Object in SortedList

beantworten | zitieren | melden

Hallo nach eine Nachtragsfrage.

ich habe eine Sortedlist mit verschiedenen Objekttypen.

Ich würde jetzt gerne eine Methode schreiben, der ich die SortedList übergebe und ein Objekttyp. als ergebnis würde ich gerne eine SortedList bekommen, wo nur die Object eingefügt sind vom übergenen Objecttyp.

z.B.
SortedList mit 12 int, 13 string usw.

methode(sortedlist, int)

Ergebnis 12 int in sortedlist

Ist das möglich?

Pedro
private Nachricht | Beiträge des Benutzers
progger
myCSharp.de - Member

Avatar #avatar-2094.gif


Dabei seit:
Beiträge: 1.271
Herkunft: Nähe von München

beantworten | zitieren | melden

Ja das müsste gehen. Ich habe mal ein Beispiel geschrieben, das überprüft, ob ein Objekt von einem bestimmten Typ ist:

private bool test(object obj,Type type){
	return type.IsInstanceOfType(obj);
}
Gibt aber auch true zurück, wenn obj die Instanz einer Klasse ist, die von type geerbt hat/abgeleitet ist!
Das müsstest du halt für dich entsprechend umbauen. Vielleicht gibt es aber auch noch eine andere/bessere Methode.

Gruß,
progger
A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Tja, du prüfst mit "is" wie gehabt, aber gegen eine Parametervariable vom Typ "Type". Beim Aufruf musst du typeof(int) anstellt von int angeben.
private Nachricht | Beiträge des Benutzers
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

beantworten | zitieren | melden

Danke.

habe es jetzt so umgesetzt.


public SortedList getObjectList(Type type) 
{
	SortedList tempList = new SortedList();
	for (int i = 0, s = _sortedList.Count; i < s; i++) 
	{
		
		if (!(type.IsInstanceOfType(_sortedList.GetByIndex(i))))
		{
			continue;
		}
		tempList.Add(_sortedList.GetKey(i),_sortedList.GetByIndex(i));
	}
	return tempList;
}


getObjectList(typeof(int));

Danke!

Pedro
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Pedro_15,

nichts gegen deinen Code (auch wenn ich foreach statt for nehmen würde), aber wie kommt es, dass in der List so unterschiedliche Objekttypen enthalten sind? Könnte ein Hinweis auf schlechtes Design sein und wenn du uns die Umstände schilderst, dann habe wir vielleicht eine bessere Lösung für dich.

herbivore
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4.221
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Obwohl ich nicht weiss wofür man so was braucht

GuckstDu: SortedList.GetIndexOfValue(type)

Wenn der Wert >-1 ist dann hast Du den Index und kannst damit den Key ziehen (der Wert ist ja type)

Oder was willst Du bezwecken...
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
private Nachricht | Beiträge des Benutzers
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

beantworten | zitieren | melden

Danke für die Antworten.

@herbivore

Ok ich probiere es mal zu schildern, was ich mache.

Ich habe eine abstrakte Klasse Dokument, von der Leite ich Worddokument und Exceldokument ab. (Beispiel einwenig geändert)

Jetzt lese ich ein Verzeichnis ein und ermittle um welches Dokument es sich handelt und erzeuge eine Instanze z.B. Worddokument und schreibe sie in die SortedList.

Im allgemeinen greife ich das Objekt in der Liste immer über Dokument ab.
Jetzt will ich aber alle ExcelDokument aus der Liste oder alle WordDokumente.

Ich könnte ja in der Schleife auf eine Methode aus Dokument zugreifen und den DokumentenType ermitteln und damit selektieren. Aber ich dachte es ist besser auf die objektdefinition zuzugreifen.

Für Designvorschläge bin ich immer zu haben.

Danke Pedro!

PS: foreach ist eine super idee, irgenwie vergesse ich das immer.
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo Pedro_15!

Ich glaube Herbivore möchte in Deinem konkreten Fall darauf hinaus, dass Du schon beim Einlesen der versch. Dokumente diese in versch. Listen packen solltest. Also lies alle *.doc und pack sie in ListeDoc, lies alle *.xls und pack sie in ListeExcel usw...

Dann brauch man hinterher auch nicht erst sortieren, oder suchen, und das Prg. läuft wahrscheinlich schneller.

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo norman_timo,

ich glaube das ist keine gute Idee. Denn
1. Ich verwende so nur eine Liste von Dokumenten in meinem System.
2. Wenn ein neuer Objecttyp hinzukommt, brauche ich nur eine neue Dokumenten Klasse erstellen und beim einlesen berücksichtigen. Fertig. Wenn ich für jedes Dokumentenklasse eine eigene Liste aufbaue, ist es schwierig die neue Liste anzusprechen ohne denn ganzen Code zu überarbeiten.

Aber was sagen die anderen dazu?

Pedro
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo Pedro_15!

Und wenn Du die Liste in der Dokumenten Klasse hälst?

So eine Art Dokumentencontainer?

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
sheitman
myCSharp.de - Member



Dabei seit:
Beiträge: 1.047

beantworten | zitieren | melden

Ist halt die Frage wie Aufwendig diese Typevergleichen ist...

Ich hätte die Unterscheidung warscheinlich mit einem enum gemacht:

enum DocumentType {
Word,
Excel
}

wobei dann deine Basisklasse Dokument ein entsprechendes abstraktes get-Property vom Typ DocumentType bekommt, und in den Unterklassen entsprechend zurück gegeben wird.

Dann könntest du darüber die Unterscheidung machen.

Hast du ja auch schon beschrieben

Bei deiner Liste kannst du noch Generics benutzen, falls du .Net 2.0 hast (Typ Dokument)
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Das Halten Elemente verschiedener Typen in einer gemeinsamen Liste ist nicht das Problem - im Gegenteil. Eine Liste je Typ ist genauso schlecht wie ein Typvergleich auf einer Liste. Das Problem ist der Typvergleich selbst. Manuelle Typprüfung ist fast immer ein Zeichen schlechten OO-Designs. Hier sollten entsprechende Interfaces helfen auf jegliche Art von Typvergleich zu verzichten.

Der Nachteil eines manuellen Typvergleichs liegt in der Änderungsanfälligkeit. Bekommst du einen weiteren Typen in die Liste, so musst du den Listencode anfassen, d.h. einen weiteren Typvergleich hinzufügen (bei der Mehr-Listen-Version müßte eine weitere Liste angelegt werden, im Prinzip noch schlechter).

Löst du das mittels Interfaceimplementierung, so ist keinerlei Codeanpassung nötig. Genau das unterscheidet gutes von schlechtem Design: Robustheit und Flexibilität gegenüber Änderungen.
private Nachricht | Beiträge des Benutzers
sheitman
myCSharp.de - Member



Dabei seit:
Beiträge: 1.047

beantworten | zitieren | melden

@svenson
ok, dann wäre demzufolge pedros bisheriger ansatz genau richtig

hast du da mal ein beispiel was deiner meinung nach gutes design wäre?
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Definiere ein Interface, welches die Methoden definiert, die auf den Listenelementen ausgeführt werden sollen. Halte in der Liste nur noch Interfaces, keine Objekte mehr. Rufe Interface-Methoden anstelle der Objekt-Methoden auf und nutze dazu Polymorphie.

Beispiel: Je nach Typ soll eine völlig andere Methode ausgeführt werden, einmal drucken, einmal speicher, whatever.

Definiere eine Listeninterface und genau eine Methode namens DoListOperation(). Implementiere DoListOperation() einmal als Drucken, Speichern, etc.!

Fertig. Kein Typvergleich, einfach Element aus der Liste holen und DoListOperation() aufrufen.

Noch dynamischer: Implementiere anstelle DoListOperation() auf dem Interface eine Methode (GetListOperation()), die einen Delegaten zurückliefert, den du aufrufen kannst (Strategie-Pattern). Nun kann für jede Klasse von außen (z.B. über ein XML-File) konfiguriert werden, welche Methode aufgerufen wird.
private Nachricht | Beiträge des Benutzers
sheitman
myCSharp.de - Member



Dabei seit:
Beiträge: 1.047

beantworten | zitieren | melden

@svenson
achso, sowas meintest du... ok, das ist ja klar.

ich seh auch, was das problem bei meiner idee wäre:
wenn ich einen neuen dokumententyp häte, müßte ich das enum anpassen :-/

aber ansonsten spricht ja nix dagegen, oder hab ich nochwas übersehen?
Zitat
Noch dynamischer: Implementiere anstelle DoListOperation() auf dem Interface eine Methode (GetListOperation()), die einen Delegaten zurückliefert, den du aufrufen kannst (Strategie-Pattern). Nun kann für jede Klasse von außen (z.B. über ein XML-File) konfiguriert werden, welche Methode aufgerufen wird.
nur mal der interesse halber:
was genau müßte denn die methode zurück geben?

weil du das thema "über xml" angesprochen hast, würde ich vermuten einen string, der den methodennamen oer sowas anthält, den ich dann über refleection aufrufe?

oder wie?
private Nachricht | Beiträge des Benutzers
norman_timo
myCSharp.de - Member

Avatar #avatar-1775.jpeg


Dabei seit:
Beiträge: 4.506
Herkunft: Wald-Michelbach (Odw)

beantworten | zitieren | melden

Hallo nochmal!

Jetzt ist halt die Frage, wieviele "alte" Klassendefinitionen sind bereits vorhanden und wieviele werden da noch dazu kommen?

Ich kann Dir nur vollkommen Recht geben, Svenson, das mit der Mehr-Listen-Variante ist nix für gutes Design.

Ich hab das mal unter dem Aspekt Quick-And-Dirty betrachtet, und je nachdem wieviel Aufwand betrieben werden darf/kann/soll, ist natürlich zu entscheiden, ob ich das in Deiner vorgeschlagenen Variante nachziehe, oder ob ich eine Q-and-D Lösung bevorzuge.

Aber das muss hier jeder selbst entscheiden.

Du hast aber Recht, da er nach Design-Aspekte gefragt hatte, wäre es wohl besser gewesen erst mal genau darüber nachzudenken :-)

Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Zitat
Original von sheitman
ich seh auch, was das problem bei meiner idee wäre:
wenn ich einen neuen dokumententyp häte, müßte ich das enum anpassen :-/

Genau. Ob du nun einen Typ mit "is" vergleichst, oder ein Typ-Enum einführst, ist gehuppt wie gesprungen.
Zitat
nur mal der interesse halber:
was genau müßte denn die methode zurück geben?

Das hängt natürlich davon ab, was aus Sicht der Liste sinnvoll ist. Kann ich ohne Kenntniss deines Codes nicht sagen. In den meisten Fällen dürfte es aber eine void-Funktion werden.
Zitat
weil du das thema "über xml" angesprochen hast, würde ich vermuten einen string, der den methodennamen oer sowas anthält, den ich dann über refleection aufrufe?

Noch besser wäre etwas anderes: Du lagerst diese Funktion in eine weitere Klasse aus. Auf diese greifst du wiederum via Interface zu. Wenn du diese Klasse in ein eigenes Assembly packst, kannst du zur Laufzeit entscheiden, welches Implementierung du benutzen willst. Du hast damit quasi eine PlugIn-Architektur geschrieben. Welches konkretes Assembly du lädst konfigurierst du in einer XML-Datei.

Du kannst nun nicht nur zwischen Methoden per Konfiguration umschalten, sondern sogar durch einfaches Einkopieren weiterer DLLs weitere Funktionen hinzufügen. Wunderbares Konzept, z.B. für Speichern in verschiedenen Formaten (Export-Plugins).

Um es nochmal zu betonen: Mit einigen wenigen Ausnahmen ist "is" immer ein Zeichen schlechten Designs. Manchmal ist das vertretbar, wenn sich das auf einen kleinen abgeschotteten Teil des Codes bezieht. Statt hier mit zusätzlichen Interfaces und Klassen zu hantieren geht man den "kurzen Weg". Wenn man z.B. genau weiss, dass sich an der Zahl der Typen niemals was ändern wird, dann ist das vertretbar, obwohl man sich bewußt sein sollte, dass "niemals" oder "immer" Begriffe sind, die in der professionellen Softwareentwicklung mit Vorsicht zu geniessen sind (niemals ist die Zeitspanne bis zum gegenteiligen Wunsch des Kunden).

"is" ist notwendig, wo man z.B. schlechtes Design nutzen muss, oder bei bestimmten generischen Ansätzen. In fachlichem Code hat "is" aber nie was zu suchen.
private Nachricht | Beiträge des Benutzers
Pedro_15
myCSharp.de - Member



Dabei seit:
Beiträge: 375
Herkunft: In der Nähe von Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo,
Zitat
Ich habe eine abstrakte Klasse Dokument, von der Leite ich Worddokument und Exceldokument ab.

@svenson
Dann finde ich meinen Ansatz doch gar nicht so schlecht. Den die abstrakte Klasse ist doch fast wie dein Interface. Ich muss aber dazu sagen, dass das Interface noch nicht mein Freund ist und komme damit im OOP Design noch nicht richtig klar.

Ich spreche bei mir im gesamten Code nur die Dokumenten Teil des Objektes an.
Leider kam jetzt bei einem spez. Dokumenten Type eine Eigenschaft dazu. Die habe ich in der Abgeleiteten Klasse eingefügt. Bei einer Funktion brauch ich jetzt diesen Objekttyp mit der Eigenschaft, deswegen meine Frage nach der Erkennung welches Objekt ich habe.

Vielleicht kannst du noch etwas dazu sagen, wie du das Problem gelöst hättest.

Danke Pedro
private Nachricht | Beiträge des Benutzers
Noodles
myCSharp.de - Experte



Dabei seit:
Beiträge: 4.644
Herkunft: Leipzig

beantworten | zitieren | melden

Mit Interfaces erreichst Du aber eine losere Kopplung.
Such mal im Forum nach Microkernel oder evtl. Contract First.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo norman_timo,
Zitat
Ich glaube Herbivore möchte in Deinem konkreten Fall darauf hinaus, dass Du schon beim Einlesen der versch. Dokumente diese in versch. Listen packen solltest.
Nein, ich meinte es so wie sevenson es in seinem ersten Beitrag schreibt.

Hallo Pedro_15, hallo Noodles,

ich bin eh nicht so ein Interface-Fan. Deshalb finde ich die Lösung mit der abstrakten Klasse voll ok. Aber auch ohne meine Vorliebe, ist vom Design her hier eine abstrakte Klasse wohl das Passendere.

herbivore
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Wenn die angedeutete Flexibilität nicht erforderlich ist, spricht auch nichts gegen eine abstrakte Oberklasse. Hauptsache man ist sich der potentiellen Nachteile bewußt und kann sicher sein, dass sie in diesem Szenario keine Rolle spielen.
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4.221
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Eine Kombination aus Beidem ist oftmals die beste Lösung....

Ein Interface erstellen.
Eine Basisklasse erstellen welche das Interface implementiert. Diese Klasse implementiert somit das Default-Verhalten des Interfaces.

Programmiert wird gegen das Interface.

Nun leiten die ersten paar Klassen alle von dieser Basisklasse ab.... Wenn man an den Punkt gelangt wo eine Ableitung nicht möglich ist erstellt man eine neue Klasse welche das Interface implementiert.... diese ist dann (weil nur gegen Interface programmiert wurde) sofort lauffähig.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
private Nachricht | Beiträge des Benutzers