Hi Leute,
ich möchte mir ein kleines Konstrukt bauen, nur leider meckert der Complier dabei rum 😦
Ich möchte eine Liste von Objekten halten und wenn ein Typ reinkommt, dann soll er aus einem Dictionary eine Objekt sich holen.
Ganz einfach dachte ich mir.
public Dictionary<Type, Buisness.MessageObjects.AbstractMessageBroker<AbstractMessage>> BrockerList
ganz einfach hinzufügen von meiner Abgeleiteten Klasse
BrockerList.Add(typeof(Buisness.MessageObjects.TextMessage.TextMessage),
new Buisness.MessageObjects.TextMessage.TextMessageBroker());
Die Klasse Textmessage Broker sieht so aus:
public class TextMessageBroker : AbstractMessageBroker<TextMessage>
Der Kompiler schreit hier mit
Error 3 The best overloaded method match for 'System.Collections.Generic.Dictionary <System.Type,Team.Buisness.MessageObjects.AbstractMessageBroker <Team.Buisness.MessageObjects.AbstractMessage>>.Add(System.Type, Team.Buisness.MessageObjects.AbstractMessageBroker <Team.Buisness.MessageObjects.AbstractMessage>)' has some invalid arguments C:\Daten\Projekte\SanSoft.Team.090525\Buisness\MessageHandlingLibary\MessageHandling.cs 22 13 MessageHandlingLibary
Error 4 Argument '2': cannot convert from 'Team.Buisness.MessageObjects.TextMessage.TextMessageBroker' to 'Team.Buisness.MessageObjects.AbstractMessageBroker <Team.Buisness.MessageObjects.AbstractMessage>' C:\Daten\Projekte\SanSoft.Team.090525\Buisness\MessageHandlingLibary\MessageHandling.cs 23 17 MessageHandlingLibary
Er ist doch die gleiche Klasse warum kann er das nicht konvertieren. Oder will er hier auch eine generische Schreibweise haben?
"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein
Hallo,
hast Du mal versucht, das von Hand zu casten?
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Danke Mark,
das wäre auch mein nächster Gedanke gewesen:
BrockerList = new Dictionary<Type, Team.Business.MessageObjects.AbstractMessageBroker<AbstractMessage>>();
Team.Business.MessageObjects.AbstractMessageBroker<AbstractMessage> newTextMessageBroker =
(Team.Business.MessageObjects.AbstractMessageBroker<AbstractMessage>)
new Business.MessageObjects.TextMessage.TextMessageBroker();
bekomme hier den Fehler
Error 1 Cannot convert type 'Team.Business.MessageObjects.TextMessage.TextMessageBroker' to 'Team.Business.MessageObjects.AbstractMessageBroker<Team.Business.MessageObjects.AbstractMessage>' C:\Daten\Projekte\Team.090525\Buisness\MessageHandlingLibary\MessageHandling.cs
"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein
Hallo,
ich glaube so kannst Du das vergessen...
Der Kern des Problems läßt sich reduzieren auf:
public abstract class AbstractType {}
public class ImplementingType : AbstractType{}
public class MyClass<T>{}
public class Test
{
Test()
{
MyClass<ImplementingType> obj = new MyClass<ImplementingType>();
// der cast in der folgenden Zeile produziert bereits einen Fehler
MyClass<AbstractType> abstractObj = (MyClass<AbstractType>)obj;
}
}
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Der Kern des Problems läßt sich reduzieren auf:
MyClass<ImplementingType> obj = new MyClass<ImplementingType>(); // der cast in der folgenden Zeile produziert bereits einen Fehler MyClass<AbstractType> abstractObj = (MyClass<AbstractType>)obj;
... womit wir wieder beim Thema sind, dass Ko- und Kontravarianz bei Generics momentan nicht geht. Kommt aber ab .NET 4.0.
Genauere Erklärung und eine Lösungsmöglichkeit gibt's u.a. in List<Unterklasse> auf List<Oberklasse> casten
Gruß,
dN!3L
Danke dN!3L,
hab dazu auch eine Presentation gefunden: http://startbigthinksmall.wordpress.com/2009/11/24/alles-vertragssache-ko-und-kontravarianz-in-c/
mein Problem ist damit nicht gelöst, muss schauen ob ich es irgendwie umgehen kann.
"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein
mein Problem ist damit nicht gelöst, muss schauen ob ich es irgendwie umgehen kann.
Ja, hab mich auch schon öfter drüber geärgert.
Einzige Lösung ist momentan ein Konvertierung. In ReadOnlyBaseList <TBase, TDerived> - Ein hilfreicher Wrapper gibt's ja schon eine Möglichkeit für Listen, für Dictionaries geht z.B. folgendes:
Dictionary<string,FileStream> rawDictionary = new Dictionary<string,FileStream>();
Dictionary<string,Stream> pseudoCastedDict = rawDictionary.ToDictionary(kvp => kvp.Key,kvp => (Stream)kvp.Value);
Gruß,
dN!3L
Nein, die vernünftige Lösung ist nicht mit einer abstrakten Klasse sondern einem Interface zu arbeiten.
Nein, die vernünftige Lösung ist nicht mit einer abstrakten Klasse sondern einem Interface zu arbeiten.
Kann man dann aber genausowenig casten.
Die Lösung demnach also generell mit der Basisklasse/dem Interface arbeiten.
Gruß,
dN!3L
Danke für eure Ratschläge, hab das ganze mal ohne Generischen Rückgabewert gemacht, die Liste hält jetzt Objekte. Brauche leider einen Cast dafür. 😦
public class MessageHandling
{
public Dictionary<Type, object> BrockerList
{
get;
set;
}
/// <summary>
/// Initializes a new instance of the <see cref="T:MessageHandling"/> class.
/// </summary>
public MessageHandling()
{
BrockerList = new Dictionary<Type, object>();
Team.Business.MessageObjects.IAbstractMessageBroker<TextMessage> newTextMessageBroker =
new Business.MessageObjects.TextMessage.TextMessageBroker();
BrockerList.Add(typeof(Business.MessageObjects.TextMessage.TextMessage),
newTextMessageBroker);
}
public Team.Business.MessageObjects.AbstractMessageBroker<IAbstractMessage> GetBrockerForType(Type messageType)
{
Team.Business.MessageObjects.AbstractMessageBroker<IAbstractMessage> ob =
(Team.Business.MessageObjects.AbstractMessageBroker<IAbstractMessage>)
BrockerList[messageType];
return ob;
}
}
EDIT:
So der Compiler beschwert sich nicht mehr. Nur noch bei der Ausführung 😦
"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein