none
Generische Methoden verstehen und anwenden RRS feed

  • Frage

  • Hallo,

    um meinen Code effizienter zu machen (und mir ca 500 Zeilen zu sparen) möchte ich zum ersten Mal Generische Methoden verwenden.

    Ich habe ein Testprogramm geschrieben:

        class Program
        {
            static void Main(string[] args)
            {
                Eins eins = new Eins();
                Zwei zwei = new Zwei();
                eins.ID = 1;
                zwei.ID = 2;
                TellID<Zwei>(ref zwei);
            }
    
            static void TellID<T>(ref T myObject)
            {
                Console.WriteLine(myObject.ID);
            }
        }
    
        public class Mother
        {
            public int ID;
        }
    
        public class Eins : Mother { }
        public class Zwei : Mother { }

    Wie zu sehen ist, will ich auf die jeweilige ID der Objekte verschiedenener Klassen zugreifen, welche alle von der Klasse Mother erben. Aber der Zugriff myObject.ID funktioniert nicht. Vielleicht sind Generische Methoden da auch gar nicht angebracht, aber auch wenn ich versuche ein Objekt (eins oder zwei) an eine Methode methode(Mother object) zu senden, geht das wegen der fehlenden Konvertierung schief. Eine Konvertierung von eins zu Mother motherObject bekomme ich nicht hin. 

    Wie muss ich vorgehen? Welche Möglichkeiten habe ich?


    www.mehlhop.com


    • Bearbeitet frank me Montag, 17. Februar 2014 14:55
    Montag, 17. Februar 2014 14:54

Antworten

  • Hallo Frank!
     
    So wie Du das gemacht hast, könntes Du deiner Methode jeden beliebigen Typ übergeben
    und nicht jeder hat eine ID-Eigenschaft. Du mußt der Methode daher mitteilen, daß
    als Typ nur von Mother abgeleitete Typen erlaubt sind:
        static void TellID<T>(ref T myObject) where T : Mother
       {
          Console.WriteLine(myObject.ID);
       }
     
    HTH
     
    Grüße
    Thomas
     
    • Als Antwort markiert frank me Montag, 17. Februar 2014 15:15
    Montag, 17. Februar 2014 15:04
  • Hallo,
    für deinen hier gezeigten Anwendungsfall ist eine generische Methode möglich, aber nicht zwingend notwendig.
    Da beide Klasse von Mother erben und es deiner Methode egal ist welche weiteren Eigenschaften noch vorhanden sind, kannst du auch ein Objekt von Mother verlangen:

    static void TellID(Mother myObject)//Methodenkopf
    TellID(ref zwei);//Der Aufruf ist wie gewohnt
    //Hinweis: ref brauchst du nur, wenn es sich um Strukturen handelt, Klassen werden immer per ref übergeben

    Wenn du trotzdem eine generische Methode verwenden möchtest, kannst du den Typ einschränken:

    static void TellID<T>(T myObject) where T : Mother

    Das sorgt dafür, das T in seiner Vererbungshierachie auf Mother treffen muss. An dieser Stelle kannst du natürlich auch eine Schnittstelle angeben. Innerhalb der Funktion weißt dann T alle Member von Mother auf.
    Auch hier brauchst du das ref-Schlüsselwort nur, wenn es sich um Strukturen handelt. Diese können aber nicht erben, lediglich Schnittstellen implementieren. Somit wird es überflüssig.

    Du kannst mit where auch noch einschränken, dass der Typ einen Parameterlosen Konstruktor haben muss. Das kann von Klassen erfüllt werden und wird von allen Strukturen erfüllt:

    static void TellID<T>(T myObject) where T : Mother, new()
    new() muss dabei immer als letzte Einschränkung stehen.


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert frank me Montag, 17. Februar 2014 15:16
    Montag, 17. Februar 2014 15:06
    Moderator

Alle Antworten

  • Hallo Frank!
     
    So wie Du das gemacht hast, könntes Du deiner Methode jeden beliebigen Typ übergeben
    und nicht jeder hat eine ID-Eigenschaft. Du mußt der Methode daher mitteilen, daß
    als Typ nur von Mother abgeleitete Typen erlaubt sind:
        static void TellID<T>(ref T myObject) where T : Mother
       {
          Console.WriteLine(myObject.ID);
       }
     
    HTH
     
    Grüße
    Thomas
     
    • Als Antwort markiert frank me Montag, 17. Februar 2014 15:15
    Montag, 17. Februar 2014 15:04
  • Hallo,
    für deinen hier gezeigten Anwendungsfall ist eine generische Methode möglich, aber nicht zwingend notwendig.
    Da beide Klasse von Mother erben und es deiner Methode egal ist welche weiteren Eigenschaften noch vorhanden sind, kannst du auch ein Objekt von Mother verlangen:

    static void TellID(Mother myObject)//Methodenkopf
    TellID(ref zwei);//Der Aufruf ist wie gewohnt
    //Hinweis: ref brauchst du nur, wenn es sich um Strukturen handelt, Klassen werden immer per ref übergeben

    Wenn du trotzdem eine generische Methode verwenden möchtest, kannst du den Typ einschränken:

    static void TellID<T>(T myObject) where T : Mother

    Das sorgt dafür, das T in seiner Vererbungshierachie auf Mother treffen muss. An dieser Stelle kannst du natürlich auch eine Schnittstelle angeben. Innerhalb der Funktion weißt dann T alle Member von Mother auf.
    Auch hier brauchst du das ref-Schlüsselwort nur, wenn es sich um Strukturen handelt. Diese können aber nicht erben, lediglich Schnittstellen implementieren. Somit wird es überflüssig.

    Du kannst mit where auch noch einschränken, dass der Typ einen Parameterlosen Konstruktor haben muss. Das kann von Klassen erfüllt werden und wird von allen Strukturen erfüllt:

    static void TellID<T>(T myObject) where T : Mother, new()
    new() muss dabei immer als letzte Einschränkung stehen.


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert frank me Montag, 17. Februar 2014 15:16
    Montag, 17. Februar 2014 15:06
    Moderator
  • Herzliche Dank Euch Beiden! 

    Das wird mir viel Arbeit (und Fehleranfälligkeit) sparen. :)

    PS: Programmieren macht mir viel Spaß, besonders dann, wenn ich was Neues verstehe.


    www.mehlhop.com

    Montag, 17. Februar 2014 15:18