myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » Objekte identifizieren
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Objekte identifizieren

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern


sra ist offline

Objekte identifizieren

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo

Ich bin gerade dabei ein kleines Spiel zu programmieren. Nun habe ich einen Timer gemacht, der bei jedem Tick für alle Objekte, die sich bewegen können (IMoveable) in einer ArrayList (Objects) die Methode move() aufzurufen, und danach die refresh() Methode des Fensters (ist bloss ein kleines Projekt und ich arbeite mit GDI+).

Mein Problem ist nun das Identifizieren von Objekten. Ich will eigentlich alle Objekte durchlaufen,welche das Interface IMoveable implementieren. Dazu habe ich folgenden Code:

C#-Code:
foreach(IMoveable Object in this.m_Level.Objects)
            {
                Object.move();
            }

Aber irgendwie kommt er nie in zu dem Object.move(), da er gar nie in die Schleife fällt.

Dann hab ich mit der Klasse direkt (Turkey) und einer for Schleife probiert versucht:

C#-Code:
for(int i = 0; i < this.m_Level.Objects.Count; i++)
            {
                if(this.m_Level.Objects[i].GetType().ToString() == "demGrenyBattle.Game.Objects.Turkey")
                {
                    ((Turkey)this.m_Level.Objects[i]).move();
                }

                this.m_Window.Refresh();
            }

Auch das funktioniert nicht, weil er kein einziges mal in die if Anweisung springt. Gebe ich aber über eine MessageBox in der for Schleife den Typen des jeweiligen Objektes aus, dann gibt er mir durchaus auch "demGrenyBattle.Game.Objects.Turkey" aus.

Hat jemand eine Idee? Bin wirklich seit ner halben Stunde am probieren.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von sra am 14.02.2006 12:55.

14.02.2006 12:51 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.862
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Den Typennamen als String zu vergleichen ist murks. Du kannst die Typen direkt vergleichen.

Ansich kann bei deiner foreach Schleife nicht viel schiefgehen. Implementieren die Klassen wirklich IMovable? Ist die Collection auch nicht leer?

Du meintest er kommt erst gar nicht in die Schleife, meinst du damit es passt kein Objekt auf IMovable oder das er die Schleife nicht erreicht? Dann müsste in dem Code vorher was schiefgehen.
14.02.2006 13:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wie kann ich denn rausfinden, ob ein Objekt von einem bestimmten Typen ist (ohne es mit einem anderen Objekt zu vergleichen)? Habe nur die Stringlösung gefunden :/

Zum anderen: Die ArrayList ist nicht leer - es sind alle Objekte vorhanden. In die Schleife komme ich nur im ersten Codebeispiel nicht, da dort die Abfrage ja bereits in der Schleife drin ist (foreach). Im zweiten Beispiel mit der for Schleife komme ich rein, und mache ich direkt in der for-Schleife ein MessageBox.show(), der mir den Typen des jeweiligen Objektes ausgibt, dann kommt wie gesagt dieser Typ vom der Turkeyklasse. Durch die if Abfrage schafft es das Objekt trotzdem nicht.

btw. Ist es auch möglich abzufragen in einer if Anweisung, ob ein Objekt ein bestimmtes Interface implementiert?
14.02.2006 13:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
marsgk marsgk ist männlich
myCSharp.de-Mitglied

Dabei seit: 04.06.2005
Beiträge: 1.439
Entwicklungsumgebung: Notepad++ + csc + nmake
Herkunft: Linz, Austria


marsgk ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



mycsharp.de  Moderationshinweis von herbivore (14.08.2013 15:05):

Link korrigiert
 
14.02.2006 13:27 Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo sra,

ja, das geht mit dem is-Operator. Aber Vorsicht: explizite Typ-Abfragen sind ein Indiz für schlechtes Design.

herbivore
14.02.2006 13:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke - ich werds mal probieren. Allerdings denke ich nicht, dass es damit geht, da es ja in der foreach auch nicht geht. Hat jemand eine Idee, warum meine foreach nicht geht? Ihr könnt davon ausgehen, dass Objects gefüllt ist mit mehreren Objekten, wovon mindestens 3 das Interface IMoveable implementieren und vom Typ Turkey sind.

Ich hab echt keine Idee mehr
14.02.2006 13:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo sra,

ich denke, dass er erst gar nicht zu dem foreach kommt. Denn käme er dort hin und würden in this.m_Level.Objects Objekte sein, die IMoveable nicht implementieren, würdest du eine Exception bekommen.

foreach(IMoveable Object in this.m_Level.Objects) heißt, dass alle Objekte in this.m_Level.Objects IMoveable implementieren müssen und nicht etwas, dass das foreach nur für die Objekte ausgeführt wird, die IMoveable implementieren.

herbivore
14.02.2006 13:41 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

hm... dann habe ich foreach nicht richtig verstanden? :/

Dann mach ich es mal ganz banal. Ich habe in einer ArrayList einige Objekte, die das Interface implementieren, und einige die dies nicht tun. Der Unterschied besteht in erster Linie darin, dass IMoveable Objekte eine Methode move() haben, welche ihre Koordinaten manipuliert. Nun hab ich einen Timer, welcher alle x ms bei allen beweglichen Objekten diese Methode aufrufen soll, damit diese ihre neue Position berechnen und danach darstellen.

Komischerweise geht es mit dem is Operator in der for schleife. Allerdings bin ich auch der Meinung, dass dies nicht wirklich eine schöne Lösung ist.
14.02.2006 13:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo sra,

du könntest dir einen Enumerator schreiben, der nur die Objekte, die IMovable implementieren, aufzählt. Ein Beispiel für einen (etwas anderen) Enumerator findest du in  foreach iteration gleichzeitig über mehrere arrays . Ist aber für einen Anfänger bestimmt eine Herausforderung.

herbivore
14.02.2006 13:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Is schon traurig, was man als "Programmierlehrling" bis ins 4te Lehrjahr gelehrt bekommt smile

Ich werd mich mal an deinen Code wagen, obwohl er für mich wirklich eine Nummer zu gross aussieht (nur schon die Rekursion). Aber im Moment quält mich noch eine andere, mit Sicherheit recht einfache Frage.

Im onPaint des frmMain hab ich den Code zum Darstellen meiner Objekte (dieses mal alle und nicht nur die mit dem Interface großes Grinsen ). Mein Problem ist, dass ich von einem anderen objekt aus dieses onPaint Ereignis auslösen muss. Ich dachte das geht ganz einfach, wenn ich dem Objekt eine Referenz auf die frmMain mitgebe, und dann vom Objekt aus .Refresh() auslöse. Leider ist dem nicht so (kein Kompilierfehler, keine Exception).

Wie kann ich das bewerkstelligen?
14.02.2006 14:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo sra,

warum musst du das von einem anderen Objekt aus machen? Ich denke, dass wäre nicht notwendig. Im Gegenteil: Ein Objekt sollte in sich abgeschlossen sein. Versuche das Programm so umzustellen, dass frmMain sich selbst Refreshed.

herbivore
14.02.2006 14:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das muss so sein, weil ich eine Klasse habe, die den ganzen Gameloop managed. Das heisst in ihr ist der Timer, der die Objekte in seinem Event bewegt, in ihr wird der Level instantiert (und in diesem wiederum die Levelobjects...).

Ich denke es ist nur sauber getrennt, wenn ich den ganzen Code nicht im Code des Fensters habe. Oder was meint ihr?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von sra am 14.02.2006 14:57.

14.02.2006 14:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
UschkinRedSunshine UschkinRedSunshine ist männlich
myCSharp.de-Mitglied

avatar-1829.png


Dabei seit: 18.10.2005
Beiträge: 68


UschkinRedSunshine ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Original von sra
Is schon traurig, was man als "Programmierlehrling" bis ins 4te Lehrjahr gelehrt bekommt smile

Traurig wenn man sich in seiner Bildung auf andere verlaesst und nicht aktiv selbst lernt...

Sinnvoller Ansatz waere auch einfach nur eine "DoSomething" Methode einzufuehren, so durchlaeufst du alle deine Objekte, startest DoSomething, und alle Objekte "bewegen" sich selbst
14.02.2006 15:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo sra,

Zitat:
Ich denke es ist nur sauber getrennt, wenn ich den ganzen Code nicht im Code des Fensters habe. Oder was meint ihr?

das, was du da abgetrennt hast, ist der Controler im MVC-Pattern. Die Überlegung ist grundsätzlich sinnvoll. Da der Controler aber in der Regel ohnehin von der Anwendungsart abhängt (Konsole, WindowsForms, Web, ...), würde ich ihn nicht vom (ebenfalls anwendungsartabhängigen) View (also hier dem Form) trennen.

Wenn du es aber doch trennst, sollte der Controler das View kennen (bzw. sogar erzeugen) und kann dann auch problemlos Refresh aufrufen.

herbivore

PS:

Zitat:
Traurig wenn man sich in seiner Bildung auf andere verlaesst und nicht aktiv selbst lernt...

Also ich habe gerade in diesem Thread den Eindruck, dass sra sich um das aktiv Selbstlernen bemüht.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von herbivore am 14.02.2006 17:13.

14.02.2006 17:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
UschkinRedSunshine UschkinRedSunshine ist männlich
myCSharp.de-Mitglied

avatar-1829.png


Dabei seit: 18.10.2005
Beiträge: 68


UschkinRedSunshine ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Offtopic:

Zitat:
Original von herbivore
Also ich habe gerade in diesem Thread den Eindruck, dass sra sich um das aktiv Selbstlernen bemüht.

Mag sein, wobei die Aussage sich anhoerte wie "Ich verlange das mir alles beigebracht wird, ich aber nichts selbst erarbeiten will"

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von UschkinRedSunshine am 14.02.2006 17:22.

14.02.2006 17:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo UschkinRedSunshine,

für mich nicht. Dazu kenne ich einfach genug gute Leute, die aktiv selber lernen, und trotzdem bzw. gerade deshalb bedauern, dass die Qualität der (berufs-)schulischen Ausbildung schlecht ist.

herbivore
14.02.2006 17:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich werd mir das mal überlegen Herbivore - danke... meld mich wohl morgen mit dem nächsten Problem großes Grinsen

Zu dem lernen-Ding kann ich sagen, dass ich leider im Geschäft bisher nur mit vb und asp zu tun hatte, und dass ich in der Schule speziell im objektorientierten Programmieren sehr gute Noten habe. Dazu kommt, dass wir noch ein Semester haben bis die Lehre fertig ist (3 Lektionen programmieren die Woche), und wir in ca. 2 Wochen mal mit Designpatterns anfangen werden. Von da her finde ich das schon schlecht.
14.02.2006 21:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo sra,

hier kommt die Klasse MovableEnumerator, mit der du genau das tun kannst, was du willst.

EDIT: Weiter  unten gibt es eine Implementierung, bei der der gewünschte Elementtyp als Typparameter übergeben werden kann.

C#-Code:
foreach (IMovable mov in new MovableEnumerator (al)) {
   mov.Move ();
}

C#-Code:
using System;
using System.Collections;

public class MovableEnumerator : IEnumerator, IEnumerable
{
   private IEnumerator    _ienum;

   public MovableEnumerator (ICollection icoll)
   {
      _ienum = icoll.GetEnumerator ();
   }

   public Object Current
   {
      get { return _ienum.Current; }
   }

   public bool MoveNext ()
   {
      while (_ienum.MoveNext ()) {
         if (_ienum.Current is IMovable) {
            return true;
         }
      }
      return false;
   }

   public void Reset ()
   {
      _ienum.Reset ();
   }

   public IEnumerator GetEnumerator ()
   {
      return this;
   }
}

interface IMovable
{
   void Move ();
}

public class Movable : IMovable
{
   public void Move ()
   {
   }
}

public class NonMovable
{
}

abstract class App
{
   public static void Main (string [] astrArg)
   {
      ArrayList al = new ArrayList ();
      al.Add (new Movable ());
      al.Add (new NonMovable ());
      al.Add (new Movable ());
      al.Add (new NonMovable ());
      al.Add (new Movable ());

      foreach (IMovable mov in new MovableEnumerator (al)) {
         Console.WriteLine (mov.GetType ());
      }
   }
}

Im Gegensatz zu  foreach iteration gleichzeitig über mehrere arrays habe ich auf zwei geschachtelte Klassen verzichtet und nur eine Enumerator-Klasse geschrieben und diese Klasse mit einem Trick (return this) foreach-geeignet gemacht.

herbivore
15.02.2006 08:45 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
sra sra ist männlich
myCSharp.de-Mitglied

avatar-175.png


Dabei seit: 21.01.2004
Beiträge: 230
Entwicklungsumgebung: Visual Studio
Herkunft: Luzern

Themenstarter Thema begonnen von sra

sra ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

yeah - Vielen Dank smile
werds mir gleich anschauen!
15.02.2006 10:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,

eine überarbeitete Version des MovableEnumerator findet ihr als Iter.Filter [EDIT]und später auch als Iter.Type[/EDIT] in  Hilfreiche Iteratoren / Improving Foreach.

herbivore
24.02.2006 11:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,

der MovableEnumerator funktionierte ja nur für IMovable. Hier kommt ein Iterator für beliebige Typen. Er listet nur die Elemente der Aufzählung auf, die vom angegebenen Typ sind. Für IMovable sieht der Aufruf so aus:

C#-Code:
foreach (IMovable mov in new IterType<IMovable> (al)) {
   mov.Move ();
}

C#-Code:
public class IterType<T> : IEnumerator<T>, IEnumerable<T> where T : class
{
   //-----------------------------------------------------------------------
   protected IEnumerator  _enumerator;

   //=======================================================================
   public IterType (IEnumerable enumerable)
   {
      _enumerator = enumerable.GetEnumerator ();
      //Reset ();
   }

   //=======================================================================
   public void Reset ()
   {
      _enumerator.Reset ();
   }

   //=======================================================================
   public bool MoveNext ()
   {
      while (_enumerator.MoveNext ()) {
         if (_enumerator.Current is T) {
            return true;
         }
      }
      return false;
   }

   //=======================================================================
   public T Current
   {
      get { return (T)_enumerator.Current; }
   }

   //=======================================================================
   Object IEnumerator.Current
   {
      get { return _enumerator.Current; }
   }

   //=======================================================================
   public void Dispose ()
   {
      // Nichts zu tun
   }

   //=======================================================================
   public IEnumerator<T> GetEnumerator ()
   {
      return this;
   }

   //=======================================================================
   IEnumerator IEnumerable.GetEnumerator ()
   {
      return this;
   }
}

herbivore
01.03.2006 20:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 14 Jahre.
Der letzte Beitrag ist älter als 14 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 08.08.2020 02:43