Cast-Probleme mit Interface

luigied

Mitglied
Guten Morgen @all,

ich glaube, ich sehe zur Zeit mal wieder den Wald vor lauter Bäumen nicht.

Ich habe in VB .NET eine Klasse ClassicAuthentication, welche ein Interface IAuthentication implementiert. Beide liegen in einer dll.

Wenn ich jetzt in meinem Hauptprogramm allerdings diese nutzen will bekomme ich eine InvalidCastException.

Code:
Dim auth As IAuthentication = New ClassicAuthentication()
            auth.setParams(params)
            Dim oo As Object() = {src.getParam("IP"), CType(src.getParam("Port"), Short), DirectCast(auth, IAuthentication), src.makeParamString}

Bei dem DirectCast wird mir die Exception geworfen. Weiss jemand, woran das liegen könnte?

Danke, schonmal.

Mfg LuigiEd
 
Hi

Wenn ich es richtig verstanden hab, erfordert DirectCast einen Typ als zweiten Parameter. Ein Interface stellt jedoch keinen Typ dar.

Ich frag mich aber, warum du casten willst. "auth" hat doch schon den "Zieltyp"
 
Es sollen später noch weitere Klassen, die IAuthentication implementieren hinzugefügt werden. Ich möchte hier verschiedene Klassen als dll laden, die alle ebenfalls ein Interface (IConnector) implementieren. Bei diesem ist festgelegt, dass die connect-Methode der implementierenden Klasse unter anderem einen Parameter, der die Authentifikation darstellt besitzt. Da es aber verschiedene Authentifizierungsarten gibt (geben soll). Muss der methode eine Klasse, die das IAthentification-Interface implementiert übergeben werden.

Oder gibt es noch einen Weg das anders zu machen?

mfg

Edit: Zieltyp sollte etwas allgemeineres sein, als die konkrete Umsetzung der Authentification. Damit ich das dann, egal, welche konkrete Auth von dem Konnektor verwendet wird , über das Interface auf dessen Methoden zugreifen kann.

In Java kann ich eine Klasse über ein Interface casten
 
Zuletzt bearbeitet:
Aber dafür musst du doch nicht casten.
Du hast ein IAuthentication-Objekt, deine Methode erwartet ein IAuthentication-Objekt
 
Ja, ursprünglich war ich auch dieser Meinung. Habe für diesen speziellen fall zwar jetzt ein notdürftiges workaround gefunden, aber an einer anderen Stelle taucht das Gleiche Problem wieder auf.

Code:
Dim conn As IConnector = ConnectorMap(Id)

In der ConnectorMap steckt bis dahin ein Objekt von MSSQLConnector.Connectors.MSSQLConnector. Doch an dieser Stelle bekomme ich folgende Exception:

Das Objekt des Typs "MSSQLConnector.Connectors.MSSQLConnector" kann nicht in Typ "BasicConnector.IConnector" umgewandelt werden.

Mein MSSQLConnector implementiert allerdings IConnector und sollte deshalb auch in diesen umgewandelt werden können.

Das dürfte doch theoretisch kein Problem sein, oder?

Sollte ich vlt. erwähnen, dass sowohl das Interface, als auch die implemetierende Klasse in externen Bibliotheken liegen? Auf die Interface-Assembly wird jeweils von dem MSSQLConnector- und meinem Hauptprojekt verwiesen.
Der MSSQLConnector liegt dann als Assmbly vor und wird über Reflection geladen nd instanziiert.

mfg
 
Zuletzt bearbeitet:
Hi.
Wenn ich es richtig verstanden hab, erfordert DirectCast einen Typ als zweiten Parameter. Ein Interface stellt jedoch keinen Typ dar.
Warum sollte ein Interface kein Typ sein? DirectCast fordert, dass einer der beiden Typen von dem anderen erbt oder den Typ implementiert.
Ja, ursprünglich war ich auch dieser Meinung. Habe für diesen speziellen fall zwar jetzt ein notdürftiges workaround gefunden, aber an einer anderen Stelle taucht das Gleiche Problem wieder auf.

Code:
Dim conn As IConnector = ConnectorMap(Id)

In der ConnectorMap steckt bis dahin ein Objekt von MSSQLConnector.Connectors.MSSQLConnector. Doch an dieser Stelle bekomme ich folgende Exception:
Du meinst Compiler-Fehler, oder?!
Mein MSSQLConnector implementiert allerdings IConnector und sollte deshalb auch in diesen umgewandelt werden können.
Kann es sein, dass du gehörig mit Namensräumen durcheinander kommst? Und das IConnector in dem Kontext etwas anderes ist als BasicConnector.IConnector?

\edit: Insbesondere (da ich gerade nochmal deine Bemerkung über Reflection gelesen habe) kann es sein, das du das Interface-Assembly neu erstellt hast, aber nicht beide abhängigen Bibliotheken ebenfalls? So dass die Type-ID vom Interface welches MSSQLConnector implementiert ungleich und somit inkompatibel zur Type-ID des Interface in deiner Anwendung ist?

Gruß
 
Zuletzt bearbeitet:
Hi deepthroat,

danke für deine Antwort.

Ich hatte extra alle Bibliotheken neu kompiliert. (also die abhängigen als letztes ;) ) Trotzdem hatte ich weiter diese Runtime-Exception ;) (InvalidCastException) Der Compiler findet den Cast ganz vernünftig und hat mir seinen Segen gegeben, aber irgendwie hat die CLR eben immer das letzte Wort. :D

Ich habe jetzt einen kleinen Umweg über Reflections genommen und siehe da: es funktioniert.

Code:
Dim t As Type = ConnectorMap(Id).GetType
            Dim conn As Object = Activator.CreateInstance(t)
            conn = ConnectorMap(Id)
            Dim m As System.Reflection.MethodInfo = t.GetMethod("method")
            Dim struct As String = m.Invoke(conn, Nothing)

Jetzt würde mich interessieren, in wie weit dieser Weg performance-technisch schlechter ist, als der Cast über das Interface.

mfg LuigiEd
 
Hi.
Ich hatte extra alle Bibliotheken neu kompiliert. (also die abhängigen als letztes ;) ) Trotzdem hatte ich weiter diese Runtime-Exception ;) (InvalidCastException)
Und hast du auch die Referenzen neu gesetzt? Also Assembly-Referenz entfernt, dann neu eingefügt? Und auch in jedem Projekt Debug bzw. Release Builds verwendet?
Ich habe jetzt einen kleinen Umweg über Reflections genommen und siehe da: es funktioniert.

Code:
Dim t As Type = ConnectorMap(Id).GetType
            Dim conn As Object = Activator.CreateInstance(t)
            conn = ConnectorMap(Id)
            Dim m As System.Reflection.MethodInfo = t.GetMethod("method")
            Dim struct As String = m.Invoke(conn, Nothing)

Jetzt würde mich interessieren, in wie weit dieser Weg performance-technisch schlechter ist, als der Cast über das Interface.
Vermutlich wird es "performance-technisch" nicht gerade das gelbe vom Ei sein, vor allem ist es aber häßlich ;-)

Gruß
 
Hast du mal die Informationen aus t angeschaut und dann die implementierten Interfaces verglichen mit GetType(IConnector)? Möglicherweise findest du dann Infos was anders ist (Versionsnummer, public key, ...).
 
@deepthroat: Hatte ich, dachte ich gemacht. Werd das nochmal überprüfen.
@Muepe32: Das werd ich mir mal ansehen. Klingt gut

Kann es eventuell daran liegen, dass ich hier noch mit .NET 2.0 arbeite? Ist ja auch nicht mehr das Neueste ^^
 
Zurück