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

Dictionary<Type,MyClass<MyAbstract>> MyClass<MyConcret>-Values hinzufügen [wird gelöst mit C# 4.0]
LastGentleman
myCSharp.de - Member

Avatar #avatar-1696.jpg


Dabei seit:
Beiträge: 1274
Herkunft: Österreich

Themenstarter:

Dictionary<Type,MyClass<MyAbstract>> MyClass<MyConcret>-Values hinzufügen [wird gelöst mit C# 4.0]

beantworten | zitieren | melden

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
Zitat
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
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
LastGentleman
myCSharp.de - Member

Avatar #avatar-1696.jpg


Dabei seit:
Beiträge: 1274
Herkunft: Österreich

Themenstarter:

beantworten | zitieren | melden

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
Zitat
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
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Zitat von MarsStein
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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dN!3L am .
private Nachricht | Beiträge des Benutzers
LastGentleman
myCSharp.de - Member

Avatar #avatar-1696.jpg


Dabei seit:
Beiträge: 1274
Herkunft: Österreich

Themenstarter:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Zitat von LastGentleman
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
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10084

beantworten | zitieren | melden

Nein, die vernünftige Lösung ist nicht mit einer abstrakten Klasse sondern einem Interface zu arbeiten.
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Zitat von FZelle
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
private Nachricht | Beiträge des Benutzers
LastGentleman
myCSharp.de - Member

Avatar #avatar-1696.jpg


Dabei seit:
Beiträge: 1274
Herkunft: Österreich

Themenstarter:

beantworten | zitieren | melden

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 :(
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von LastGentleman am .
"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
private Nachricht | Beiträge des Benutzers