Casablanca: Generic

Hallo Forum,

ich habe eine Generic-Methode wie folgt:

  
       private void SetValue<T>(T myList) where T : List<T>  
        {  
            items.AddRange(myList.Select(list => new SelectListItem  
            {  
                Text = list.ToString("dd.MM.yyyy"),  
                Value = list.ToString("dd.MM.yyyy"),  
            }));  
  
            ...  
        }  

An dieser Stelle bekomme ich ein Problem mit "list.ToString("dd.MM.yyyy")", das besagt, dass die "ToString"-Methode 0 Parameter ertwartet und keinen 1. Wenn aber die Methodensignatur so geändert wird:

  
       private void SetValue<T>(T myList) where T : List<DateTime>  

klappt alles wunderbar. Diese Signatur der Methode muss aber genau so sein wie oben beschrieben. Kann man da was tun, damit diese Zeile "list.ToString("dd.MM.yyyy")" trotzdem funktioniert?

Gruß

  1. Hi,

    private void SetValue<T>(T myList) where T : List<T>
            {
                items.AddRange(myList.Select(list => new SelectListItem
                {
                    Text = list.ToString("dd.MM.yyyy"),
                    Value = list.ToString("dd.MM.yyyy"),
                }));

    ...
            }

      
    Naja - entweder Du sagst/verlangst, daß Deine Liste Elemente enthält, die von DateTime abgeleitet sind, dann kannst Du auch die entsprechenden Methoden benutzen.  
    Oder Du erlaubst alle Listenelemente, dann können halt auch nur allgemein bekannte Methoden benutzt werden.  
      
    Ansonsten bliebe nur noch ein Cast auf DateTime an den Stellen, an denen Du DateTime-spezifische Methoden aufrufen willst.  
    Ist aber irgendwie widersinnig - einerseits sollen laut Signatur auch andere Elemente erlaubt werden, aber andererseits DateTime-spezifische Methoden auf diesen Elementen aufgerufen werden ...  
      
    cu,  
    Andreas
    
    -- 
    [Warum nennt sich Andreas hier MudGuard?](http://MudGuard.de/)  
    [O o ostern ...](http://ostereier.andreas-waechter.de/)  
      
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.  
    
    
  2. Tach!

    private void SetValue<T>(T myList) where T : List<T>

    Was bitte bezweckst du denn damit? T darf nur eine Liste von sich selbst sein? Das heißt, alle Elemente sind wiederum Listen von Listen von Listen von ...?

    items.AddRange(myList.Select(list => new SelectListItem {
                    Text = list.ToString("dd.MM.yyyy"),
    An dieser Stelle bekomme ich ein Problem mit "list.ToString("dd.MM.yyyy")", das besagt, dass die "ToString"-Methode 0 Parameter ertwartet und keinen 1.

    List<T> erbt ToString() von Object und diese Methode erwartet keinen Parameter. Ein Item, das als "list" bezeichnet wird, ist auch seltsam. Aber gut, wenn es eine Liste von Listen von ... ist, dann stimmt das wieder.

    Diese Signatur der Methode muss aber genau so sein wie oben beschrieben.

    Das glaub ich nicht.

    Kann man da was tun, damit diese Zeile "list.ToString("dd.MM.yyyy")" trotzdem funktioniert?

    Du erwartest offensichtlich, dass list vom Typ DateTime ist. Das ist es aber nicht, sondern von einem Typ, der zu List<T> kompatibel ist. Das kann so nicht klappen.

    dedlfix.

  3. Hi,

    vielen Dank für die Antworte.
    Ich verstehe jetzt das Problem. Was Generic angeht, bin ich nicht die Experte. Ich bin momentan am rumprobieren. Ich habe die Methode so verstandenm. dass die einen Wert/Parameter - myList - von einem beliebigen Typ erhält, der eine Liste ist, die eine Reihe von demselben Typ enthält. Mir ist aber nciht ganz klar, was der Type-Angabe T bei SetValue<T> aussagt. Abgesehen von dem Inhalt, wie soll dann die Methode aussehen, die alle Listenarten, u.a. auch eine Liste, die DateTime Elemente beinhaltet, aufnehmen kann.

    Gruß

    1. Tach!

      Ach ja, hier wollte ich doch auch noch drauf antworten.

      Was Generic angeht, bin ich nicht die Experte. [...] Ich habe die Methode so verstandenm. dass die einen Wert/Parameter - myList - von einem beliebigen Typ erhält, der eine Liste ist, die eine Reihe von demselben Typ enthält. Mir ist aber nciht ganz klar, was der Type-Angabe T bei SetValue<T> aussagt.

      T ist ein Platzhalter, der bei der Verwendung den dann angegebenen Typ repräsentiert. Andere Buchstaben sind auch möglich, das T hat sich eingebürgert, wenn man nur einen variablen Typ hat. Meist nimmt man für weitere das U und so weiter. Eine List<T> wird bei beispielsweise als List<DateTime> verwendet. Dann sind die Elemente darin vom Typ DateTime. Das T ist in dem Fall also ein DateTime. Das weiß aber der Code der List<T> nicht und kann deshalb nicht auf Mitglieder von DateTime zugreifen. Es muss dafür erst eine Einschränkung angegeben werden, also das "where T: DateTime". Dann allerdings kann T nur noch DateTime und abgeleitete Typen repräsentieren.

      Wenn nun T nur vom Typ List<T> sein darf, dann gibt es eine Rekursion ohne Abbruch.

      Abgesehen von dem Inhalt, wie soll dann die Methode aussehen, die alle Listenarten, u.a. auch eine Liste, die DateTime Elemente beinhaltet, aufnehmen kann.

      Die kann dann keine Einschränkung in der where-Klausel haben. Im Gegenzug kannst du dann nicht auf spezielle Eigenschaften zugreifen, ohne einen Typecast gemacht zu haben. Vielleicht willst du ja nicht T entgegennehmen sondern eine List<T> oder IList<T> (ohne where-Klausel) Der konkrete Typ kann dann durchaus auch eine List<irgendwas> sein. Nur hat die Methode dann keine Ahnung davon (ohne Typecast). Aber es ist auf alle Fälle eine Liste.

      dedlfix.