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

  • »
  • Community
  • |
  • Diskussionsforum
Funktionsaufruf mittels Templateobjekt
Stone1984
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

Funktionsaufruf mittels Templateobjekt

beantworten | zitieren | melden

Guten Abend,

seit einigen Stunden bin ich schon dabei eine Lösung für einen Funktionsaufruf von einem Template (Generic) objekt ausgehend. Leider bekomme ich dabei den Fehler:

"TList enthält keine Funktion update"

Der zugrundeliegende Code sieht folgendermaßen aus:
Das Hauptprogramm ist:


MySQLDataList<CompanyList> companies = new MySQLDataList<CompanyList>();
companies.createEmptyObject();
companies.getDataList().data.Add(new Company { ID = 1, NAME = "Firma 1" });
companies.getDataList().data.Add(new Company { ID = 2, NAME = "Firma 2" });
companies.getDataList().data.Add(new Company { ID = 3, NAME = "Firma 3" });
companies.getDataList().data.Add(new Company { ID = 4, NAME = "Firma 4" });
CompanyList companyList = companies.getDataList();

CompanyList tempCompany = new CompanyList();
tempCompany.data.Add(new Company { ID = 2, NAME = "Firma 5" });
companies.update(tempCompany);

und die Klasse CompanyList ist:


class CompanyList
{
    public CompanyList()
    {
        data = new List<Company>();
    }

    public List<Company> data { get; set; }

    public void update(CompanyList a_companyList)
    {
        for (int i = 0; i < a_companyList.data.Count; i++)
        {
            update(a_companyList.data[i]);
        }
    }

    /**
     * \brief       Update eines Datensatzes.
     * \param[in]   Datensatz der geupdated werden soll.
     */
    public void update(Company a_company)
    {
        for (int i = 0; i < data.Count; i++)
        {
            if (data[i].ID == a_company.ID)
            {
                data[i].NAME = a_company.NAME;
            }
        }
    }
}

public class Company
{
    public int ID { get; set; }
    public string NAME { get; set; }
}

und schließlich die Klasse MySQLDataList:


class MySQLDataList<TList>
{
    public MySQLDataList()
    {
            
    }

    public void update(TList a_dataList)
    {
        m_dataList.update(a_dataList);
    }

    public void createEmptyObject()
    {
        m_dataList = new JavaScriptSerializer().Deserialize<TList>("{\"data\":[]}");
    }

    public TList getDataList()
    {
        return m_dataList;
    }

    TList m_dataList = default(TList);          //!< Liste mit Daten aus der Datenbank.
}

Probleme macht mir in dieser Klasse der Aufruf:


m_dataList.update(a_dataList);

Ich bin davon ausgegangen, da sich m_dataList in diesem Template vom Typ CompanyList ist und CompanyList die Funktion update besitzt, dass dieser Aufruf möglich wäre. Für mein TList ist sichergestellt, das jede Klasse, die für TList übergeben wird eine update-Methode enthält.

Kennt jemand eine Möglichkeit, wie ich in dem vorliegenden Programm einen gültigen Aufruf von update, ausgehend vom Objekt TList erzeugen kann? Gibt es evtl. in C# anderweitige Methoden, mit denen ich derartige generische Aufrufe realisieren kann?

Bei meiner Such bin ich bisher leider auf nichts vergleichbares gestoßen.
private Nachricht | Beiträge des Benutzers
Jompikumpi
myCSharp.de - Member



Dabei seit:
Beiträge: 13

beantworten | zitieren | melden

Mir fehlt das Interface das die Funktion „update“ enthält und das auch für TList als Einschränkung definiert ist und daher auch für CompanyList implementiert sein muss.

Siehe auch https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-interfaces.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Jompikumpi am .
private Nachricht | Beiträge des Benutzers
Stone1984
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

beantworten | zitieren | melden

Vielen Dank für den Hinweis. Das bedeutet, das ich zur Klasse CompanyList folgenden Code hinzufügen muss:


interface IListInterface<TList>
{
    void update(TList a_companyList);
}

class CompanyList : IListInterface<CompanyList>
{
......

Nur wie mache ich es dann in der Klasse MySQLDataList? Auf dieser Seite funktioniert es bei mir noch nicht.
private Nachricht | Beiträge des Benutzers
Papst
myCSharp.de - Experte



Dabei seit:
Beiträge: 350
Herkunft: Kassel

beantworten | zitieren | melden

Was du da machst sieht schon sehr abenteuerlich und kompliziert aus.

Du kommst von PHP - richtig? Schau dir am besten die Grundlagen und Pattern von C# an.

Zu deinem Problem:
Aktuell kann jeglicher Typ als TList genutzt werden. Wenn du dort eine update-Methode haben willst, musst du den Typen einschränken, auf entweder einen Typen, der update implementiert hat oder ein Interface, dass dieses vorschreibt.
Das geht über Generic Constraints.

Edit: oh sorry.. exakt der gleiche Link :)
Einfach nochmal den Link durchlesen... den Punkt mit dem where ...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Papst am .
private Nachricht | Beiträge des Benutzers
Stone1984
myCSharp.de - Member



Dabei seit:
Beiträge: 7

Themenstarter:

beantworten | zitieren | melden

@Papst: Vielen Dank für den Hinweis mit dem where. Nachdem ich die Zeile


class MySQLDataList<TList> where TList : IListInterface<TList>

in MySQLDataList ergänzt hatte läuft es einwandfrei und eröffnet neue Möglichkeiten.

Bin übrigends hauptsächlich aus der hardwarenahen C++ Welt. Bastelle aber nebenbei auch mit PHP, SQL und C# an Anwendungen herum.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Zitat von Stone1984

Bin übrigends hauptsächlich aus der hardwarenahen C++ Welt.

Das sieht man an Deinen Bezeichnern wie a_, Uppercase-Properties und Co; typisch aus der C++ Welt ;-)
Macht man in C# jedoch weniger bis gar nicht.

Nur als Hinweis: [Artikel] C#: Richtlinien für die Namensvergabe
private Nachricht | Beiträge des Benutzers