Laden...

getType() vergleichen

Erstellt von polofreak vor 17 Jahren Letzter Beitrag vor 17 Jahren 5.952 Views
polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren
getType() vergleichen

Hi zusammen ich möchte zwei Typen miteinander vergleichen, aber ich komm nie in mein IfStatement rein, kann mir einer von euch sagen warum?

if (scheiss.GetType() == (ag.GetType()))

if (scheiss.GetType().Equals(ag.GetType()))

das hab ich probiert wenn ich die Variablen beobachte dann sieht das für mich SEHR gleich aus!!
any ideas?

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo polofreak,

also wenn man Typen vergleichen will, ist meinstens was faul. Das muss man quasi nie.

Bei deinen Code ist jedenfalls klar, warum es nicht geht. Du vergleichst die Referenzen zweier verschiedener Type-Objekte, auch wenn diese für den gleichen Typ stehen.

Vergleiche die Typen als Strings (das zeigt schon, wie krank das ganze ist) oder verwende wechselseitig Type.IsSubclassOf.

herbivore

S
8.746 Beiträge seit 2005
vor 17 Jahren

Bei mir liefert ein Typvergleich immer true, egal ob ==, Equals oder ReferenceEquals.

M
1.439 Beiträge seit 2005
vor 17 Jahren

SDK-Doku:

For two objects x and y that have identical runtime types, Object.ReferenceEquals(x.GetType(),y.GetType()) returns true.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo zusammen,

okokok, überzeugt, aber zu "also wenn man Typen vergleichen will, ist meinstens was faul. Das muss man quasi nie" stehe ich weiterhin.

herbivore

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

was ist aber dann falsch?? 🙁 was muss ich machen zu sehen ob die vom gleichen typ sind?
zu "also wenn man Typen vergleichen will, ist meinstens was faul. Das muss man quasi nie"
na wie soll ich es dann machen? Ich hab eine Klasse Shape, eine Klasse ShapeCollection, und drei weitere Klassen die von Shape erben wenn ich jetzt die geerbten Klassen wild gewürfelt in ein ShapeCollectionObject rein Stecke, wie soll ich denn sonst raus finden um welche Unterklasse es sich handelt?

M
1.439 Beiträge seit 2005
vor 17 Jahren
polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

cool werde ich gleich mal probieren 😉

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

hm geht nicht 🙁
hab es jetzt mal so probiert aber in die if geht er immernoch nicht!

ShapeCollection SC = new ShapeCollection();
Arbeitsgang blubber = new Arbeitsgang();
           foreach(Shape sh in graphControl1.Nodes)
                SC.Add(sh);
            foreach (Shape scheiss in SC)
                if (scheiss is Arbeitsgang) //Arbeitsgang ist von Shape abgeleitet
                {
                    blubber = (Arbeitsgang)scheiss;
                }
S
8.746 Beiträge seit 2005
vor 17 Jahren

Vermutlich wird eben kein Objekt dieses Typs in der der Collection hängen... entsprechende Code hast du ja nicht gepostet.

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

Die collection wird in einer DLL gefüllt, aber hier mal zwei Screenshots wo der Typ angezeigt wir
und die sind doch gleich oder nicht?

So wenn ich mach

if (scheiss is Shape)

dann geht es 🙁 aber ich will doch auch den Typ der davon geerbt hat wissen. und desweiteren fliegt dann ne Exception in der Zeile

blubber = (Arbeitsgang)scheiss;

in der steht:

Unable to cast object of type 'Netron.GraphLib.AG.Arbeitsgang' to type 'Netron.GraphLib.AG.Arbeitsgang'.

bin ich jetzt besoffen oder mein VS

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo polofreak,

wenn ich jetzt die geerbten Klassen wild gewürfelt in ein ShapeCollectionObject rein Stecke, wie soll ich denn sonst raus finden um welche Unterklasse es sich handelt?

was soll ich sagen, meistens muss man das eben gar nicht. Waum meinst du denn, dass zu müssen?

herbivore

S
8.746 Beiträge seit 2005
vor 17 Jahren

Erzeugst du die Objekte via Reflection (CreateInstance)? Falls ja, wird ein Versionierungsproblem vorliegen.

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

also die Objekte der Unterklassen an sich erzeuge ich via Reflektion, aber wenn ich dann zur Laufzeit Objekte dieser Unterklassen erzeuge, dann mach ich das mit new.

Das mit dem Versionierungsproblem könnte es schon sein, aber wo muss ich jetzt den Fehler suchen??

@herbivore: meine Unterklassen haben unterschiedliche Properties. Wenn ich jetzt einfach auf das Property Kosten zugreife, dann haben das manche der Unterklassen und andere eben nicht! Und ich könnte auch if des Property da ist prüfen aber das wäre ja noch viel Semiprofessioneller, und wesentlich unperformanter, wenn ich bei jeder Unterklasse alle Möglichkeiten der anderen Unterklassen mitprüfen würde.

L
254 Beiträge seit 2005
vor 17 Jahren

Ich möcht mich hier ganz klar herbivore anschliessen.

Ich glaube nicht, dass du wirklich wissen musst was für Typen du zur Laufzeit hast.

Für soetwas ist genau die Interface Programmierung "erfunden" worden, so kann man die Software so Aufbauen, dass es egal ist was für konktreten Typ die Klasse hat (da die Basisklasse immer vom abstrakten Typ(dem Interface) erbt)

Darum kann herbivore so eine "grundlegende" Aussage treffen, wenn du wirklich Typen vergleichen musst (vorallem konktrete Typen einer Klasse) hast du mit grosser wahrscheinlichkeit konzeptuelle Probleme.

Bitte Poste, was du wirklich machen möchtest, wieso du diese Typenunterscheidung machen wills, dann kann dir vielleicht auf eine andere bessere Art geholfen werden.

If you can't make it, fake it.

T
73 Beiträge seit 2004
vor 17 Jahren

Hallo,

versuch mal mit dem "kollegen" von is:


...

if(scheiss is Arbeitsgang)
{
    Arbeitsgang ag;

    ag = scheiss as Arbeitsgang; //Liefert null wenns nicht geht!

    if(ag != null)
    {
    ...
    }
}


alternativ kannst du ja auch ein interface definieren um zugriff auf die benötigten methoden zu bekommen (sollte allerdings durch die vererbung ja schon definiert sein...?).

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

@ tomschrot: Danke werde ich mal probieren.

@ herbivore und Lexodus: Im Bild seht ihr einen ausschnitt aus meiner GUI. Diese gezeichneten Objekte sind Objekte der Klassen die ich neben dran geschrieben hab. (stammen aus einer DLL) Die gezeichneten Objekte werden zur Laufzeit auf eine Zeichenfläche eingefügt, und bei jedem Neueinfügen wird auch ein Objekt der entsprechenden Klasse erzeugt. Ich habe unterschiedliche Properties in den unterschiedlichen Klassen, auf die ich aus dem Hauptprogramm zugreifen will. Wenn ich mir jetzt alle Shapes der Zeichenfläche hole, schreibe ich sie alle in meine ShapeCollection. Wenn ich jetzt auf die Properties zugreifen will sollte ich aber wissen was für ein Typ es ist. Oder etwa nicht??

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

@tomschrot: auch das funktioniert leider nicht! Wahrscheinlich weil er einfach nicht casten kann. Vermutlich wegen dem schon genannten Versionskonflikt, von dem ich nicht weiß wie ich ihn angehen soll 🙁

S
5 Beiträge seit 2006
vor 17 Jahren

Kommt für dich vielleicht so was in Frage:


enum BaseClassType{Type1,Type2,TypeN};
  class BaseClass
  {
    public BaseClassType ClassType;
  }
  class Class1:BaseClass
  {
    public Class1()
    {
      ClassType = BaseClassType.Type1;
    }
  }
  class Class2 : BaseClass
  {
    public Class2()
    {
      ClassType = BaseClassType.Type2;
    }
  }

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo polofreak,

unterschiedliche Properties in den Unterklassen zu haben, auf die man von außen zugreifen will, ist ein konzeptionelles Problem 🙂

Wer will denn die Properties abfragen und warum?

Nehmen wir mal die Draw-Methode. Die ist ja in jeder Unterklasse spezifisch realisiert und kann deshalb natürlich spezifisch arbeiten, also bei Kreis mit Radius und bei Quadrat mit Kantenlänge. Aber wer muss die Eigenschaften Radius und Kantenlänge von außen abfragen? Normalerweise keiner.

Zumindest ist Shape ein klassisches Lehrbuchbeispiel, bei dem man gerade ohne Typabfragen auskommt. Lediglich beim Erzeugen und nur da spielt der konkrete Typ eine Rolle.

herbivore

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

nein es ist kein konzeptionelles Problem! Bei mir sind diese Shapes nicht nur die Visuelle-Erscheinung sondern da stecken Objekte für eine Simmulation dahinter. Somit haben sie auch um einiges mehr Properties als die Properties des aussehens. Und auf die muss zugegriffen werden, da die Shapes untereinander interagieren, und dabei müssen sie nunmal auf die Properties zugreifen.

Zu " Wer will denn die Properties abfragen und warum? " Ich aus besagtem Grund. Ausserdem wollte ich nicht eine Grundsatzdiskussion Anfangen ob es sinnvoll ist Properties zwischen den Unterklassen abzufragen oder nicht ich wollte wissen wie man das macht.

Doch leider scheint hier keiner ne wirkliche Lösung zu haben. Mich würde immernoch interessieren was es mit dem Versionskonflikt auf sich hat, denn das könnte ich mir schon sehr gut vorstellen dass es daran liegt

Mfg Polo

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo polofreak,

nein es ist kein konzeptionelles Problem! [...]

nach dem, was du im folgenden schreibst, ist es doch ein konzeptionelles Problem.

Um dieses zu lösen musst du nur die Zugriffe auf die Properties in Methoden der Unterklasse vergelegen, die in der Oberklasse als virtuell deklatiert/definiert sind.

Eine Alternative wäre vielleicht noch, Interfaces zu verwenden.

Ausserdem wollte ich nicht eine Grundsatzdiskussion Anfangen ob es sinnvoll ist Properties zwischen den Unterklassen abzufragen oder nicht ich wollte wissen wie man das macht.

So wie es dir frei steht, die Fragen zu stellen, die du für richtig hältst, steht es mir frei, die Antworten zu geben, die ich für richtig halte. 🙂

Auf die Frage, wie muss ich den Feuerstein richtig halten, damit ich meinen Backofen anbekomme, würde die richtige Antwort sein, kauf dir einen Feueranzünder.

herbivore

polofreak Themenstarter:in
181 Beiträge seit 2006
vor 17 Jahren

hm das mit dem Konzeptionellen Problem sehe ich zwar immernoch anders aber du hast schon recht, wir sind ein freies Land!
Nur kann ich jetzt konzeptionell auch nichts mehr umstellen, da ich mit dieser Diplomarbeit Ende Juni fertig sein sollte und noch so einiges offen steht, wenn ich jetzt auch noch anfange solche Sachen umzustellen komme ich auf gar keinen grünen Zweig mehr.
Ich werde wohl oder übel wenn sie mit dieser Versionierungsgeschichte nichts mehr ergibt die Props einfach in der Oberklasse definieren und im Propertygrid halt nur die anzeigen die benötigt sind. Nicht schön aber dafür selten 😉

Danke dennoch für alle Antworten

BTW: Feueranzünder heißen auch Streichhölzer oder Feuerzeug 😉

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo polofreak,

ja, aber ich meinte eben einen (Piezo-)Feueranzünder und kein Feuerzeug oder Streichhölzer. Das ist ja, was ich meine: Immer die richtige Werkzeuge oder Verfahren verwenden. 🙂

herbivore

T
512 Beiträge seit 2006
vor 17 Jahren

Es kann aber nicht sein, dass die Klasse zwar gleichen Namen haben, aber in unterschiedlichen Assemblies liegen? Bzw. dass die Assemblies in denen die Typen liegen unterschiedliche Version haben?
Lass dir mal den vollen Namen der Assembly von den Typen anzeigen.

e.f.q.

Aus Falschem folgt Beliebiges