Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   C# [C# Generics] Casting auf Abgeleitete Typen? (https://www.delphipraxis.net/84995-%5Bc-generics%5D-casting-auf-abgeleitete-typen.html)

Phoenix 24. Jan 2007 13:29


[C# Generics] Casting auf Abgeleitete Typen?
 
Gleich in die Vollen:

Ich habe eine Liste<T> und ein Item. Beide Leite ich ab, weil ich auf speziellen Liste spezielle Initialisierungen der Items brauche. Nun klappt aber das Typecasting im abgeleiteten Item von einem Verweis auf die zugehörige Liste nicht.

Kann mir wer dazu was konkretes sagen?

Hier mein Code:

Code:
using System.Collections.Generic;

namespace MyNamespace
{
    public class MyBaseList<T> : List<T>, INotifyPropertyChanged
        where T : MyBaseItem
    {
        protected Boolean _init = false;
        protected Boolean _modified = false;
        protected List<T> _deleteditems = null;
        ...
    }
}
Soweit dürfte das klar sein. Ich brauche nun noch ein Baseitem. Um in der Struktur aber sauber navigieen zu können benötigt mein Item einen Verweis auf die übergeordnete Liste:

Code:
        public class MyBaseItem : INotifyPropertyChanged
    {
        protected MyBaseList<MyBaseItem> _collection = null;
        protected Boolean _init = false;
        protected Boolean _modified = false;
        ...
    }
Das geht soweit. Nun habe ich jedoch eine abgeleitete Klasse meines BaseItems:

Code:
    public class SystemParameterList<T> : MyBaseList<T>
        where T : SysParam
    {
        IDbCommand _savecmd = null;
        Boolean _savecmdinit = false;
        IDbCommand _deletecmd = null;
        Boolean _deletecmdinit = false;

        public SystemParameterList()
            : base()
        {
            Trace.WriteLineIf(Logging.TraceLevel.TraceVerbose, "Instance Created");
        }
        ...
    }


    public class SysParam : MyBaseItem
    {
        private String _guid = "";
        private String _name = "";
        private String _value = "";
        private ValType _type = ValType.String;

        public SystemParameterList<SysParam > Collection
        {
            get { return (SystemParameterList<SysParam>)_collection; }  // genau HIER steigt der Compiler aus
            set { _collection = value; }
        }
Beim Kommentar gehts in die Hose. Er kann _collection (ist ja vom typ MyBaseList<MyBaseItem>) nicht nach SystemParameterList<SysParam> casten, obwohl SystemParameterList von MyBaseList abgeleitet ist und der SysParam freilich von MyBaseItem abgeleitet ist.

Wie kann ich das auflösen?

Phoenix 27. Jan 2007 10:33

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
*Push* :duck:

Khabarakh 27. Jan 2007 12:43

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Die Beziehung zwischen Liste und Item sind mir nicht ganz klar, vor allem weil imho bei beiden Varianten ein Widerspruch entsteht: Darf in eine abgeleitete Liste allein die entsprechende Itemklasse oder auch eine davon abgeleitete Klasse eingefügt werden?

Phoenix 27. Jan 2007 13:03

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Zitat:

Zitat von Khabarakh
Die Beziehung zwischen Liste und Item sind mir nicht ganz klar, vor allem weil imho bei beiden Varianten ein Widerspruch entsteht: Darf in eine abgeleitete Liste allein die entsprechende Itemklasse oder auch eine davon abgeleitete Klasse eingefügt werden?

Die Basisklasse (Item) muss auf der Basisklasse (Liste) ein paar Grundlegende Funktionen ausführen. Wenn ein Item gelöscht wird, so trägt es sich z.B. automatisch in die Collection _deleteditems der Liste ein und setzt deren Status auf modifiziert. Dies ist ein Teil der generischen Funktionalität der Listen und der Items.

In einer abgeleiteten Liste soll nur die entsprechende Itemklasse referenziert werden. Davon abgeleitet Klassen sollte es nach dem Design nicht mehr geben.

Das Problem ist eher andersrum:
Jedes Item braucht einen strong typed Verweis auf die zugehörige Liste.

Nur so kann ich z.B. von einem Systemparameter aus mit .Collection auf die Liste aller anderen Systemparameter kommen. Das macht jetzt hier nicht so viel Sinn, aber bei anderen Listen die es z.T. mehrfach instanziert und mit unterschiedlichen Items gibt ist es schon wichtig, alle zugehörigen Items zu erhalten, und das geht nur über die jeweilige Liste.

Khabarakh 27. Jan 2007 13:20

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Zitat:

Zitat von Phoenix
In einer abgeleiteten Liste soll nur die entsprechende Itemklasse referenziert werden. Davon abgeleitet Klassen sollte es nach dem Design nicht mehr geben.

Gut, wie ich mir es gedacht habe. Dein Typparameter bei SystemParameterList hatte mich ein wenig verwirrt ;) .
Code:
    public class MyBaseList<TItem, TSelf> : List<TItem>
        where TItem : MyBaseItem<TSelf, TItem>
    {
       
    } 

   public class MyBaseItem<TList, TSelf>
      where TList : MyBaseList<TSelf, TList>
    {
      TList list;

      public TList List
      {
         get { return list; }
         set { list = value; }
      }
    }

   public class SystemParameterList : MyBaseList<SysParam, SystemParameterList>
    {

    }

   public class SysParam : MyBaseItem<SystemParameterList, SysParam>
   {
      // base.Collection _ist_ schon eine SystemParameterList
   }
Sieht komisch aus, funktioniert aber so :zwinker: .

PS: He, wer von uns zweien verwendet hier Leerzeichen zur Formatierung :stupid: ?

Elvis 27. Jan 2007 15:22

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Zitat:

Zitat von Khabarakh
Sieht komisch aus, funktioniert aber so :zwinker:

Nee, sieht noch nicht eklig genug aus. :mrgreen:
Da fehlt jeweils die Bedingung auf den Typ selbst:
Code:
public class MyBaseList<TItem, TSelf> : List<TItem>
  where TSelf : MyBaseList<TItem, TSelf>
  where TItem : MyBaseItem<TSelf, TItem>
{

}

public class MyBaseItem<TList, TSelf>
  where TSelf : MyBaseItem<TList, TSelf>
  where TList : MyBaseList<TSelf, TList>
{
  TList list;

  public TList List
  {
    get { return list; }
    set { list = value; }
  }
}
btw: Das ist aber trotzdem alles Blödsinn.
Eine Liste ist eine Liste, ist eine Liste. Man darf die nur bis zu einem bestimmten Grad schlau machen.
So wie P's Schnipsel oben aussehen sind seine so mit Informationen vollgestopft und verknüpft, dass man sie fast gar nicht mehr benutzen kann.

Das was du da mit den Commands in der Liste machst hat da nix zu suchen. Werfe es einfach in eine eigne generische Basisklasse.
Die klinkt sich in den ListChanged event einer IBindingList ein und gut ist.
Du musst jetzt keine Listen mehr programmieren. Nur noch Ableitungen dieses Dings. Und vor allem, kannst du deine Listen auch wiederverwenden, bzw du bist nicht ständig eingeengt.

Mal ein abstrakter Bleistift der Basisklasse.
Code:
abstract class PersistenzDingens<TList, TItem> : IPersistenzDingens<TList, TItem>
  where TList : IList<TItem>, IBindingList
  where TItem : INotifyPropertyChanged
{
  readonly TList list;

  protected IList<TItem> IList
  {
    get { return (IList<TItem>)list; }
  }

  protected abstract void ItemChanged(TItem item, PropertyDescriptor propertyDescriptor);
  protected abstract void ItemAdded(TItem item);
  protected abstract void ItemRemoved(TItem item);

  public PersistenzDingens(TList list)
  {
    this.list = list;

    list.ListChanged += delegate(object sender, ListChangedEventArgs e)
    {
      TItem item = IList[e.NewIndex];
      switch (e.ListChangedType)
      {
        case ListChangedType.ItemAdded:
          ItemAdded(item);
          break;
        case ListChangedType.ItemChanged:
          ItemChanged(item, e.PropertyDescriptor);
          break;
        case ListChangedType.ItemDeleted:
          ItemRemoved(item);
          break;
        default:
          break;
      }
    };
  }
}

Phoenix 27. Jan 2007 15:38

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Zitat:

Zitat von Elvis
Eine Liste ist eine Liste, ist eine Liste. Man darf die nur bis zu einem bestimmten Grad schlau machen.
So wie P's Schnipsel oben aussehen sind seine so mit Informationen vollgestopft und verknüpft, dass man sie fast gar nicht mehr benutzen kann.

Eine Liste von Fachklassen muss ihr Fach beherrschen. Sie muss sich z.B. selber aufbauen können. Eine Subliste muss sich eingeschränkt auf das Parent-Element aufbauen können.

Zitat:

Zitat von Elvis
Das was du da mit den Commands in der Liste machst hat da nix zu suchen. Werfe es einfach in eine eigne generische Basisklasse.

Eine generische Basisklasse kennt die SP's bzw. die Statements der spezifischen Daten nicht bzw. sollte sie nicht kennen. Dafür ist sie generisch und unspezialisiert.

Eine spezialisierte Fachklasse implementiert nunmal logik, und eine spezialisierte Liste für diese Fachklasse muss auch Logik implementieren - nämlich muss eine spezialisierte Liste (z.B. Aufträge) beim Daten holen feststellen, ob sie alleine da steht (alle Aufträge holen), oder ob sie z.B. an einem Kunden hängt (nur Aufträge dieses Kunden holen).

Aber diese Diskussion ist eh hinfällig. Ich habe ein Design vorgelegt bekommen und werde dafür bezahlt dieses Design zu implementieren. Ich werde nicht dafür bezahlt an dem Design etwas eigenmächtig zu ändern und da ich nunmal von Aufträgen abhängig bin werde ich de Teufel tun hier den Designer zu verärgern. ;-)

Elvis 27. Jan 2007 15:47

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Zitat:

Zitat von Phoenix
Aber diese Diskussion ist eh hinfällig. Ich habe ein Design vorgelegt bekommen und werde dafür bezahlt dieses Design zu implementieren. Ich werde nicht dafür bezahlt an dem Design etwas eigenmächtig zu ändern und da ich nunmal von Aufträgen abhängig bin werde ich de Teufel tun hier den Designer zu verärgern. ;-)

Hmm, hoffentlich nicht gegen eine fixe Bezahlung. Das wird sich noch eine Weile hinziehen und die Beziehungen im Code werden immer enger werden.

Been there, done that, got the T-Shirt... ;)

Phoenix 27. Jan 2007 15:49

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Keine Sorge, Stundenweise :mrgreen:

Ähh... wolltest Du mir diesbezüglich nicht eigentlich noch was zusammenzippen und mailen? *g*

Elvis 27. Jan 2007 15:59

Re: [C# Generics] Casting auf Abgeleitete Typen?
 
Zitat:

Zitat von Phoenix
Keine Sorge, Stundenweise :mrgreen:

Aber bereite dich darauf vor, dass dich der Nachfolger des "Designers" dafür anschwärzen wird.
Zum Thema implementieren eines fremden, undurchdachten Designs[1] fällt mir noch das ein:
Been there, done that, have the scar to prove it...
Zitat:

Zitat von Phoenix
Ähh... wolltest Du mir diesbezüglich nicht eigentlich noch was zusammenzippen und mailen? *g*

Ja wollte ich, aber ich wusste nicht wieviel es dir wirklich bringt.
Schließlich habe ich es damals nur umgeschrieben um e lauffähig zu kriegen und die Abhängigkeit auf den CoreLabs Provider loszuwerden.
Da du anscheinend gar nicht vor zuhaben schieintst den DAL aus den Container klassen zu nehmen bringt es dir wohl noch weniger als nix. ;)

[1]wobei auf deren Seite immer wieder energisch darauf bestanden wurde, dass es nicht verkorkst sei. :wall:


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:17 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz